@vbyte/btc-dev 1.1.8 → 2.0.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 +94 -0
- package/README.md +260 -3
- package/dist/const.d.ts +3 -0
- package/dist/const.js +23 -22
- package/dist/index.d.ts +11 -11
- package/dist/index.js +10 -10
- package/dist/lib/address/api.d.ts +2 -2
- package/dist/lib/address/api.js +12 -12
- package/dist/lib/address/encode.d.ts +1 -1
- package/dist/lib/address/encode.js +24 -24
- package/dist/lib/address/index.d.ts +6 -6
- package/dist/lib/address/index.js +6 -6
- package/dist/lib/address/p2pkh.d.ts +2 -2
- package/dist/lib/address/p2pkh.js +14 -14
- package/dist/lib/address/p2sh.d.ts +2 -2
- package/dist/lib/address/p2sh.js +13 -13
- package/dist/lib/address/p2tr.d.ts +2 -2
- package/dist/lib/address/p2tr.js +13 -13
- package/dist/lib/address/p2wpkh.d.ts +2 -2
- package/dist/lib/address/p2wpkh.js +14 -14
- package/dist/lib/address/p2wsh.d.ts +2 -2
- package/dist/lib/address/p2wsh.js +13 -13
- package/dist/lib/address/script.d.ts +1 -1
- package/dist/lib/address/script.js +16 -16
- package/dist/lib/address/util.d.ts +1 -1
- package/dist/lib/address/util.js +22 -22
- package/dist/lib/meta/index.d.ts +4 -4
- package/dist/lib/meta/index.js +4 -4
- package/dist/lib/meta/locktime.d.ts +1 -1
- package/dist/lib/meta/locktime.js +12 -12
- package/dist/lib/meta/ref.js +9 -6
- package/dist/lib/meta/scribe.d.ts +2 -2
- package/dist/lib/meta/scribe.js +48 -53
- package/dist/lib/meta/sequence.d.ts +1 -1
- package/dist/lib/meta/sequence.js +16 -15
- package/dist/lib/script/decode.d.ts +2 -2
- package/dist/lib/script/decode.js +50 -15
- package/dist/lib/script/encode.d.ts +1 -1
- package/dist/lib/script/encode.js +20 -16
- package/dist/lib/script/index.d.ts +5 -13
- package/dist/lib/script/index.js +5 -14
- package/dist/lib/script/lock.d.ts +2 -2
- package/dist/lib/script/lock.js +15 -12
- package/dist/lib/script/util.js +4 -4
- package/dist/lib/script/words.js +129 -129
- package/dist/lib/sighash/index.d.ts +3 -3
- package/dist/lib/sighash/index.js +3 -3
- package/dist/lib/sighash/segwit.d.ts +2 -2
- package/dist/lib/sighash/segwit.js +15 -14
- package/dist/lib/sighash/taproot.d.ts +2 -2
- package/dist/lib/sighash/taproot.js +24 -23
- package/dist/lib/sighash/util.d.ts +2 -2
- package/dist/lib/sighash/util.js +7 -7
- package/dist/lib/signer/index.d.ts +2 -2
- package/dist/lib/signer/index.js +2 -2
- package/dist/lib/signer/sign.d.ts +1 -1
- package/dist/lib/signer/sign.js +42 -7
- package/dist/lib/signer/verify.d.ts +17 -3
- package/dist/lib/signer/verify.js +233 -3
- package/dist/lib/taproot/cblock.d.ts +1 -1
- package/dist/lib/taproot/cblock.js +14 -16
- package/dist/lib/taproot/encode.d.ts +1 -1
- package/dist/lib/taproot/encode.js +7 -7
- package/dist/lib/taproot/index.d.ts +4 -4
- package/dist/lib/taproot/index.js +4 -4
- package/dist/lib/taproot/parse.d.ts +1 -1
- package/dist/lib/taproot/parse.js +12 -14
- package/dist/lib/taproot/tree.d.ts +2 -2
- package/dist/lib/taproot/tree.js +11 -7
- package/dist/lib/tx/create.d.ts +1 -1
- package/dist/lib/tx/create.js +28 -12
- package/dist/lib/tx/decode.d.ts +2 -2
- package/dist/lib/tx/decode.js +50 -17
- package/dist/lib/tx/encode.d.ts +2 -2
- package/dist/lib/tx/encode.js +13 -16
- package/dist/lib/tx/index.d.ts +7 -7
- package/dist/lib/tx/index.js +7 -7
- package/dist/lib/tx/parse.d.ts +1 -1
- package/dist/lib/tx/parse.js +9 -9
- package/dist/lib/tx/size.d.ts +2 -2
- package/dist/lib/tx/size.js +9 -9
- package/dist/lib/tx/util.d.ts +2 -2
- package/dist/lib/tx/util.js +23 -20
- package/dist/lib/tx/validate.d.ts +1 -1
- package/dist/lib/tx/validate.js +3 -3
- package/dist/lib/witness/index.d.ts +2 -2
- package/dist/lib/witness/index.js +2 -2
- package/dist/lib/witness/parse.d.ts +2 -2
- package/dist/lib/witness/parse.js +24 -23
- package/dist/lib/witness/util.d.ts +2 -2
- package/dist/lib/witness/util.js +5 -5
- package/dist/main.cjs +2308 -1005
- package/dist/main.cjs.map +1 -1
- package/dist/module.mjs +2308 -1005
- package/dist/module.mjs.map +1 -1
- package/dist/package.json +20 -17
- package/dist/schema/base.d.ts +1 -1
- package/dist/schema/base.js +17 -13
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +2 -2
- package/dist/schema/taproot.d.ts +1 -1
- package/dist/schema/taproot.js +2 -2
- package/dist/schema/tx.d.ts +1 -1
- package/dist/schema/tx.js +4 -4
- package/dist/script.js +8 -8
- package/dist/script.js.map +1 -1
- package/dist/types/address.d.ts +4 -4
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.js +8 -8
- package/dist/types/meta.d.ts +4 -4
- package/dist/types/psbt.d.ts +2 -2
- package/dist/types/script.d.ts +2 -2
- package/dist/types/sighash.d.ts +2 -2
- package/dist/types/witness.d.ts +5 -5
- package/package.json +20 -17
- package/src/const.ts +0 -61
- package/src/index.ts +0 -13
- package/src/lib/address/api.ts +0 -50
- package/src/lib/address/encode.ts +0 -183
- package/src/lib/address/index.ts +0 -7
- package/src/lib/address/p2pkh.ts +0 -94
- package/src/lib/address/p2sh.ts +0 -96
- package/src/lib/address/p2tr.ts +0 -91
- package/src/lib/address/p2wpkh.ts +0 -94
- package/src/lib/address/p2wsh.ts +0 -92
- package/src/lib/address/script.ts +0 -63
- package/src/lib/address/util.ts +0 -87
- package/src/lib/meta/index.ts +0 -4
- package/src/lib/meta/locktime.ts +0 -57
- package/src/lib/meta/ref.ts +0 -107
- package/src/lib/meta/scribe.ts +0 -256
- package/src/lib/meta/sequence.ts +0 -146
- package/src/lib/script/decode.ts +0 -85
- package/src/lib/script/encode.ts +0 -129
- package/src/lib/script/index.ts +0 -20
- package/src/lib/script/lock.ts +0 -73
- package/src/lib/script/util.ts +0 -78
- package/src/lib/script/words.ts +0 -182
- package/src/lib/sighash/index.ts +0 -3
- package/src/lib/sighash/segwit.ts +0 -152
- package/src/lib/sighash/taproot.ts +0 -206
- package/src/lib/sighash/util.ts +0 -51
- package/src/lib/signer/index.ts +0 -2
- package/src/lib/signer/sign.ts +0 -39
- package/src/lib/signer/verify.ts +0 -88
- package/src/lib/taproot/cblock.ts +0 -96
- package/src/lib/taproot/encode.ts +0 -49
- package/src/lib/taproot/index.ts +0 -4
- package/src/lib/taproot/parse.ts +0 -65
- package/src/lib/taproot/tree.ts +0 -94
- package/src/lib/tx/create.ts +0 -90
- package/src/lib/tx/decode.ts +0 -123
- package/src/lib/tx/encode.ts +0 -155
- package/src/lib/tx/index.ts +0 -7
- package/src/lib/tx/parse.ts +0 -69
- package/src/lib/tx/size.ts +0 -68
- package/src/lib/tx/util.ts +0 -111
- package/src/lib/tx/validate.ts +0 -49
- package/src/lib/witness/index.ts +0 -2
- package/src/lib/witness/parse.ts +0 -127
- package/src/lib/witness/util.ts +0 -18
- package/src/schema/base.ts +0 -57
- package/src/schema/index.ts +0 -2
- package/src/schema/taproot.ts +0 -12
- package/src/schema/tx.ts +0 -48
- package/src/types/address.ts +0 -35
- package/src/types/index.ts +0 -8
- package/src/types/meta.ts +0 -48
- package/src/types/psbt.ts +0 -15
- package/src/types/script.ts +0 -18
- package/src/types/sighash.ts +0 -16
- package/src/types/taproot.ts +0 -41
- package/src/types/txdata.ts +0 -85
- package/src/types/witness.ts +0 -42
package/dist/lib/tx/decode.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { Stream } from
|
|
2
|
-
import { Assert } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Stream } from "@vbyte/buff";
|
|
2
|
+
import { Assert } from "@vbyte/micro-lib/assert";
|
|
3
|
+
import { COINBASE, MAX_VARINT_SIZE } from "../../const.js";
|
|
4
|
+
const MAX_TX_SIZE = 4_000_000;
|
|
5
|
+
const MAX_TX_ELEMENTS = 100_000;
|
|
5
6
|
export function decode_tx(txdata, use_segwit = true) {
|
|
6
|
-
Assert.is_bytes(txdata,
|
|
7
|
+
Assert.is_bytes(txdata, "txdata must be hex or bytes");
|
|
8
|
+
const txSize = typeof txdata === "string" ? txdata.length / 2 : txdata.length;
|
|
9
|
+
if (txSize > MAX_TX_SIZE) {
|
|
10
|
+
throw new Error(`Transaction size ${txSize} exceeds maximum ${MAX_TX_SIZE} bytes`);
|
|
11
|
+
}
|
|
7
12
|
const stream = new Stream(txdata);
|
|
8
13
|
const version = read_version(stream);
|
|
9
14
|
let has_witness = check_witness_flag(stream);
|
|
10
|
-
has_witness =
|
|
15
|
+
has_witness = use_segwit ? has_witness : false;
|
|
11
16
|
const vin = read_inputs(stream);
|
|
12
17
|
const vout = read_outputs(stream);
|
|
13
18
|
if (has_witness) {
|
|
@@ -36,7 +41,10 @@ function check_witness_flag(stream) {
|
|
|
36
41
|
}
|
|
37
42
|
function read_inputs(stream) {
|
|
38
43
|
const inputs = [];
|
|
39
|
-
const vinCount = stream.
|
|
44
|
+
const vinCount = stream.read_varint();
|
|
45
|
+
if (vinCount > MAX_TX_ELEMENTS) {
|
|
46
|
+
throw new Error(`Input count ${vinCount} exceeds maximum ${MAX_TX_ELEMENTS}`);
|
|
47
|
+
}
|
|
40
48
|
for (let i = 0; i < vinCount; i++) {
|
|
41
49
|
const txinput = read_vin(stream);
|
|
42
50
|
inputs.push(txinput);
|
|
@@ -50,21 +58,40 @@ function read_vin(stream) {
|
|
|
50
58
|
const sequence = stream.read(4).reverse().num;
|
|
51
59
|
const witness = [];
|
|
52
60
|
if (txid === COINBASE.TXID && vout === COINBASE.VOUT) {
|
|
53
|
-
return {
|
|
61
|
+
return {
|
|
62
|
+
coinbase: script_sig,
|
|
63
|
+
prevout: null,
|
|
64
|
+
script_sig: null,
|
|
65
|
+
sequence,
|
|
66
|
+
txid,
|
|
67
|
+
vout,
|
|
68
|
+
witness,
|
|
69
|
+
};
|
|
54
70
|
}
|
|
55
71
|
else {
|
|
56
|
-
return {
|
|
72
|
+
return {
|
|
73
|
+
coinbase: null,
|
|
74
|
+
prevout: null,
|
|
75
|
+
script_sig,
|
|
76
|
+
sequence,
|
|
77
|
+
txid,
|
|
78
|
+
vout,
|
|
79
|
+
witness,
|
|
80
|
+
};
|
|
57
81
|
}
|
|
58
82
|
}
|
|
59
83
|
function read_outputs(stream) {
|
|
60
84
|
const outputs = [];
|
|
61
|
-
const vcount = stream.
|
|
85
|
+
const vcount = stream.read_varint();
|
|
86
|
+
if (vcount > MAX_TX_ELEMENTS) {
|
|
87
|
+
throw new Error(`Output count ${vcount} exceeds maximum ${MAX_TX_ELEMENTS}`);
|
|
88
|
+
}
|
|
62
89
|
for (let i = 0; i < vcount; i++) {
|
|
63
90
|
try {
|
|
64
91
|
outputs.push(read_vout(stream));
|
|
65
92
|
}
|
|
66
|
-
catch (
|
|
67
|
-
throw new Error(`failed to decode output
|
|
93
|
+
catch (_error) {
|
|
94
|
+
throw new Error(`failed to decode output at index ${i}`);
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
97
|
return outputs;
|
|
@@ -72,24 +99,30 @@ function read_outputs(stream) {
|
|
|
72
99
|
function read_vout(stream) {
|
|
73
100
|
const value = stream.read(8).reverse().big;
|
|
74
101
|
const script_pk = read_payload(stream);
|
|
75
|
-
Assert.exists(script_pk,
|
|
102
|
+
Assert.exists(script_pk, "failed to decode script_pk");
|
|
76
103
|
return { value, script_pk };
|
|
77
104
|
}
|
|
78
105
|
function read_witness(stream) {
|
|
79
106
|
const stack = [];
|
|
80
|
-
const count = stream.
|
|
107
|
+
const count = stream.read_varint();
|
|
108
|
+
if (count > MAX_TX_ELEMENTS) {
|
|
109
|
+
throw new Error(`Witness element count ${count} exceeds maximum ${MAX_TX_ELEMENTS}`);
|
|
110
|
+
}
|
|
81
111
|
for (let i = 0; i < count; i++) {
|
|
82
112
|
const element = read_payload(stream);
|
|
83
113
|
if (element === null) {
|
|
84
|
-
throw new Error(
|
|
114
|
+
throw new Error(`failed to decode witness element at index ${i}`);
|
|
85
115
|
}
|
|
86
116
|
stack.push(element);
|
|
87
117
|
}
|
|
88
118
|
return stack;
|
|
89
119
|
}
|
|
90
120
|
export function read_payload(stream) {
|
|
91
|
-
const size = stream.
|
|
92
|
-
|
|
121
|
+
const size = stream.read_varint("le");
|
|
122
|
+
if (size > MAX_VARINT_SIZE) {
|
|
123
|
+
throw new Error(`Payload size ${size} exceeds maximum ${MAX_VARINT_SIZE}`);
|
|
124
|
+
}
|
|
125
|
+
return size > 0 ? stream.read(size).hex : null;
|
|
93
126
|
}
|
|
94
127
|
function read_locktime(stream) {
|
|
95
128
|
return stream.read(4).reverse().to_num();
|
package/dist/lib/tx/encode.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { TxInput, TxOutput
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import type { TxData, TxInput, TxOutput } from "../../types/index.js";
|
|
3
3
|
export declare function encode_tx(txdata: TxData, use_segwit?: boolean): Buff;
|
|
4
4
|
export declare function encode_tx_version(num: number): Buff;
|
|
5
5
|
export declare function encode_txin_txid(txid: string): Buff;
|
package/dist/lib/tx/encode.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { Assert } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { Assert } from "@vbyte/micro-lib";
|
|
3
|
+
import { COINBASE } from "../../const.js";
|
|
4
|
+
import { assert_tx_data } from "./validate.js";
|
|
5
5
|
export function encode_tx(txdata, use_segwit = true) {
|
|
6
6
|
assert_tx_data(txdata);
|
|
7
7
|
const { version, vin, vout, locktime } = txdata;
|
|
8
8
|
const buffer = [encode_tx_version(version)];
|
|
9
9
|
if (use_segwit) {
|
|
10
|
-
buffer.push(Buff.hex(
|
|
10
|
+
buffer.push(Buff.hex("0001"));
|
|
11
11
|
}
|
|
12
12
|
buffer.push(encode_tx_inputs(vin));
|
|
13
13
|
buffer.push(encode_tx_outputs(vout));
|
|
@@ -32,7 +32,7 @@ export function encode_txin_sequence(sequence) {
|
|
|
32
32
|
return Buff.num(sequence, 4).reverse();
|
|
33
33
|
}
|
|
34
34
|
export function encode_tx_inputs(vin) {
|
|
35
|
-
const raw = [Buff.
|
|
35
|
+
const raw = [Buff.create_varint(vin.length, "le")];
|
|
36
36
|
for (const input of vin) {
|
|
37
37
|
raw.push(encode_vin(input));
|
|
38
38
|
}
|
|
@@ -44,7 +44,7 @@ export function encode_vin(txin) {
|
|
|
44
44
|
encode_txin_txid(COINBASE.TXID),
|
|
45
45
|
encode_txin_vout(COINBASE.VOUT),
|
|
46
46
|
encode_script_data(txin.coinbase),
|
|
47
|
-
encode_txin_sequence(txin.sequence)
|
|
47
|
+
encode_txin_sequence(txin.sequence),
|
|
48
48
|
]);
|
|
49
49
|
}
|
|
50
50
|
else {
|
|
@@ -52,7 +52,7 @@ export function encode_vin(txin) {
|
|
|
52
52
|
encode_txin_txid(txin.txid),
|
|
53
53
|
encode_txin_vout(txin.vout),
|
|
54
54
|
encode_script_data(txin.script_sig),
|
|
55
|
-
encode_txin_sequence(txin.sequence)
|
|
55
|
+
encode_txin_sequence(txin.sequence),
|
|
56
56
|
]);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -60,7 +60,7 @@ export function encode_vout_value(value) {
|
|
|
60
60
|
return Buff.big(value, 8).reverse();
|
|
61
61
|
}
|
|
62
62
|
export function encode_tx_outputs(vout) {
|
|
63
|
-
const buffer = [Buff.
|
|
63
|
+
const buffer = [Buff.create_varint(vout.length, "le")];
|
|
64
64
|
for (const output of vout) {
|
|
65
65
|
buffer.push(encode_tx_vout(output));
|
|
66
66
|
}
|
|
@@ -68,13 +68,10 @@ export function encode_tx_outputs(vout) {
|
|
|
68
68
|
}
|
|
69
69
|
export function encode_tx_vout(txout) {
|
|
70
70
|
const { value, script_pk } = txout;
|
|
71
|
-
return Buff.join([
|
|
72
|
-
encode_vout_value(value),
|
|
73
|
-
encode_script_data(script_pk)
|
|
74
|
-
]);
|
|
71
|
+
return Buff.join([encode_vout_value(value), encode_script_data(script_pk)]);
|
|
75
72
|
}
|
|
76
73
|
export function encode_vin_witness(data) {
|
|
77
|
-
const buffer = [Buff.
|
|
74
|
+
const buffer = [Buff.create_varint(data.length)];
|
|
78
75
|
for (const param of data) {
|
|
79
76
|
buffer.push(encode_script_data(param));
|
|
80
77
|
}
|
|
@@ -86,9 +83,9 @@ export function encode_tx_locktime(locktime) {
|
|
|
86
83
|
export function encode_script_data(script) {
|
|
87
84
|
if (script !== null) {
|
|
88
85
|
Assert.is_hex(script);
|
|
89
|
-
return Buff.hex(script).prefix_varint(
|
|
86
|
+
return Buff.hex(script).prefix_varint("le");
|
|
90
87
|
}
|
|
91
88
|
else {
|
|
92
|
-
return Buff.hex(
|
|
89
|
+
return Buff.hex("00");
|
|
93
90
|
}
|
|
94
91
|
}
|
package/dist/lib/tx/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
1
|
+
export * from "./create.js";
|
|
2
|
+
export * from "./decode.js";
|
|
3
|
+
export * from "./encode.js";
|
|
4
|
+
export * from "./parse.js";
|
|
5
|
+
export * from "./size.js";
|
|
6
|
+
export * from "./util.js";
|
|
7
|
+
export * from "./validate.js";
|
package/dist/lib/tx/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
1
|
+
export * from "./create.js";
|
|
2
|
+
export * from "./decode.js";
|
|
3
|
+
export * from "./encode.js";
|
|
4
|
+
export * from "./parse.js";
|
|
5
|
+
export * from "./size.js";
|
|
6
|
+
export * from "./util.js";
|
|
7
|
+
export * from "./validate.js";
|
package/dist/lib/tx/parse.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { TxData, TxOutputTemplate } from
|
|
1
|
+
import type { TxData, TxOutputTemplate } from "../../types/index.js";
|
|
2
2
|
export declare function parse_tx(txdata: unknown, prevouts?: TxOutputTemplate[]): TxData;
|
|
3
3
|
export declare function serialize_tx(txdata: unknown): Record<string, unknown>;
|
package/dist/lib/tx/parse.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Assert } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Assert } from "@vbyte/micro-lib/assert";
|
|
2
|
+
import { create_tx, create_tx_output } from "./create.js";
|
|
3
|
+
import { decode_tx } from "./decode.js";
|
|
4
|
+
import { assert_tx_template } from "./validate.js";
|
|
5
5
|
export function parse_tx(txdata, prevouts) {
|
|
6
6
|
let tx;
|
|
7
|
-
if (typeof txdata ===
|
|
7
|
+
if (typeof txdata === "string" || txdata instanceof Uint8Array) {
|
|
8
8
|
tx = decode_tx(txdata);
|
|
9
9
|
}
|
|
10
10
|
else {
|
|
@@ -12,10 +12,10 @@ export function parse_tx(txdata, prevouts) {
|
|
|
12
12
|
tx = create_tx(txdata);
|
|
13
13
|
}
|
|
14
14
|
if (prevouts) {
|
|
15
|
-
Assert.has_items(prevouts,
|
|
15
|
+
Assert.has_items(prevouts, "prevouts must be a non-empty array");
|
|
16
16
|
for (const [idx, vin] of tx.vin.entries()) {
|
|
17
17
|
const prevout = prevouts.at(idx);
|
|
18
|
-
Assert.exists(prevout,
|
|
18
|
+
Assert.exists(prevout, `prevout not found for input index: ${idx}`);
|
|
19
19
|
vin.prevout = create_tx_output(prevout);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -31,14 +31,14 @@ export function serialize_tx(txdata) {
|
|
|
31
31
|
if (e.prevout !== null) {
|
|
32
32
|
vin.push({
|
|
33
33
|
script_pk: e.prevout.script_pk,
|
|
34
|
-
value: Number(e.prevout.value)
|
|
34
|
+
value: Number(e.prevout.value),
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
for (const e of tx.vout) {
|
|
39
39
|
vout.push({
|
|
40
40
|
script_pk: e.script_pk,
|
|
41
|
-
value: Number(e.value)
|
|
41
|
+
value: Number(e.value),
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
return { version, locktime, vin, vout };
|
package/dist/lib/tx/size.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Bytes } from
|
|
2
|
-
import type { TxData, TxInput, TxOutput, TxSize } from
|
|
1
|
+
import { type Bytes } from "@vbyte/buff";
|
|
2
|
+
import type { TxData, TxInput, TxOutput, TxSize } from "../../types/index.js";
|
|
3
3
|
export declare function get_vsize(bytes: Bytes): number;
|
|
4
4
|
export declare function get_txsize(txdata: string | TxData): TxSize;
|
|
5
5
|
export declare function get_vin_size(vin: TxInput[]): number;
|
package/dist/lib/tx/size.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { encode_tx, encode_tx_inputs, encode_tx_outputs, encode_tx_vout, encode_vin, encode_vin_witness, } from "./encode.js";
|
|
3
|
+
import { parse_tx } from "./parse.js";
|
|
4
4
|
const WIT_FLAG_BYTES = 2;
|
|
5
5
|
export function get_vsize(bytes) {
|
|
6
6
|
const weight = Buff.bytes(bytes).length;
|
|
7
|
-
const remain =
|
|
7
|
+
const remain = weight % 4 > 0 ? 1 : 0;
|
|
8
8
|
return Math.ceil(weight / 4) + remain;
|
|
9
9
|
}
|
|
10
10
|
export function get_txsize(txdata) {
|
|
@@ -12,7 +12,7 @@ export function get_txsize(txdata) {
|
|
|
12
12
|
const base = encode_tx(json, false).length;
|
|
13
13
|
const total = encode_tx(json, true).length;
|
|
14
14
|
const weight = base * 3 + total;
|
|
15
|
-
const remain =
|
|
15
|
+
const remain = weight % 4 > 0 ? 1 : 0;
|
|
16
16
|
const vsize = Math.ceil(weight / 4) + remain;
|
|
17
17
|
return { base, total, vsize, weight };
|
|
18
18
|
}
|
|
@@ -26,10 +26,10 @@ export function get_vout_size(vout) {
|
|
|
26
26
|
}
|
|
27
27
|
export function get_segwit_size(txinputs) {
|
|
28
28
|
const segwit_data = txinputs
|
|
29
|
-
.filter(e => e.witness.length > 0)
|
|
30
|
-
.map(e => e.witness);
|
|
31
|
-
return WIT_FLAG_BYTES +
|
|
32
|
-
.reduce((acc, e) => acc + encode_vin_witness(e).length, 0);
|
|
29
|
+
.filter((e) => e.witness.length > 0)
|
|
30
|
+
.map((e) => e.witness);
|
|
31
|
+
return (WIT_FLAG_BYTES +
|
|
32
|
+
segwit_data.reduce((acc, e) => acc + encode_vin_witness(e).length, 0));
|
|
33
33
|
}
|
|
34
34
|
export function get_txin_size(txinput) {
|
|
35
35
|
const bytes = encode_vin(txinput);
|
package/dist/lib/tx/util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import type { TxData, TxOutput, TxOutputTemplate, TxValue } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import type { TxData, TxOutput, TxOutputTemplate, TxValue } from "../../types/index.js";
|
|
3
3
|
export declare function transcode_tx(txdata: string | Uint8Array, use_segwit?: boolean): Buff;
|
|
4
4
|
export declare function get_txid(txdata: string | Uint8Array | TxData): string;
|
|
5
5
|
export declare function get_txhash(txdata: string | Uint8Array | TxData): string;
|
package/dist/lib/tx/util.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { Test } from
|
|
3
|
-
import { Assert } from
|
|
4
|
-
import { hash256 } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { Test } from "@vbyte/micro-lib";
|
|
3
|
+
import { Assert } from "@vbyte/micro-lib/assert";
|
|
4
|
+
import { hash256 } from "@vbyte/micro-lib/hash";
|
|
5
|
+
import { DEFAULT } from "../../const.js";
|
|
6
|
+
import { decode_tx } from "./decode.js";
|
|
7
|
+
import { encode_tx } from "./encode.js";
|
|
8
|
+
import { parse_tx } from "./parse.js";
|
|
9
|
+
import { assert_tx_template } from "./validate.js";
|
|
10
10
|
export function transcode_tx(txdata, use_segwit = true) {
|
|
11
11
|
const decoded = decode_tx(txdata);
|
|
12
12
|
return encode_tx(decoded, use_segwit);
|
|
@@ -16,21 +16,21 @@ export function get_txid(txdata) {
|
|
|
16
16
|
if (txdata instanceof Uint8Array) {
|
|
17
17
|
buffer = transcode_tx(txdata, false);
|
|
18
18
|
}
|
|
19
|
-
else if (typeof txdata ===
|
|
19
|
+
else if (typeof txdata === "object") {
|
|
20
20
|
assert_tx_template(txdata);
|
|
21
21
|
buffer = encode_tx(txdata, false);
|
|
22
22
|
}
|
|
23
|
-
else if (typeof txdata ===
|
|
23
|
+
else if (typeof txdata === "string") {
|
|
24
24
|
Assert.is_hex(txdata);
|
|
25
25
|
buffer = transcode_tx(txdata, false);
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
|
-
throw new TypeError(
|
|
28
|
+
throw new TypeError(`invalid txdata type: ${typeof txdata}`);
|
|
29
29
|
}
|
|
30
30
|
return hash256(buffer).reverse().hex;
|
|
31
31
|
}
|
|
32
32
|
export function get_txhash(txdata) {
|
|
33
|
-
if (typeof txdata ===
|
|
33
|
+
if (typeof txdata === "object") {
|
|
34
34
|
assert_tx_template(txdata);
|
|
35
35
|
txdata = encode_tx(txdata, true);
|
|
36
36
|
}
|
|
@@ -41,13 +41,13 @@ export function get_tx_value(txdata) {
|
|
|
41
41
|
assert_tx_template(tx);
|
|
42
42
|
const vin = tx.vin.reduce((acc, txin) => acc + (txin.prevout?.value ?? 0n), 0n);
|
|
43
43
|
const vout = tx.vout.reduce((acc, txout) => acc + txout.value, 0n);
|
|
44
|
-
const fees =
|
|
44
|
+
const fees = vin > vout ? vin - vout : 0n;
|
|
45
45
|
return { fees, vin, vout };
|
|
46
46
|
}
|
|
47
47
|
export function get_prevouts(txdata) {
|
|
48
48
|
assert_tx_template(txdata);
|
|
49
|
-
const prevouts = txdata.vin.map(e => e.prevout);
|
|
50
|
-
Assert.ok(prevouts.every(e => e !== null),
|
|
49
|
+
const prevouts = txdata.vin.map((e) => e.prevout);
|
|
50
|
+
Assert.ok(prevouts.every((e) => e !== null), "prevouts missing from tx");
|
|
51
51
|
return prevouts;
|
|
52
52
|
}
|
|
53
53
|
export function normalize_sequence(sequence) {
|
|
@@ -57,15 +57,18 @@ export function normalize_sequence(sequence) {
|
|
|
57
57
|
return Buff.hex(sequence, 4).reverse().num;
|
|
58
58
|
if (Test.is_uint(sequence))
|
|
59
59
|
return sequence;
|
|
60
|
-
throw new Error(
|
|
60
|
+
throw new Error(`invalid sequence value: ${String(sequence)}`);
|
|
61
61
|
}
|
|
62
62
|
export function normalize_value(value) {
|
|
63
63
|
if (Test.is_uint(value))
|
|
64
64
|
return BigInt(value);
|
|
65
|
-
if (typeof value ===
|
|
65
|
+
if (typeof value === "bigint")
|
|
66
66
|
return value;
|
|
67
|
-
throw new TypeError(
|
|
67
|
+
throw new TypeError(`invalid output value: ${String(value)}`);
|
|
68
68
|
}
|
|
69
69
|
export function normalize_prevout(prevout) {
|
|
70
|
-
return {
|
|
70
|
+
return {
|
|
71
|
+
script_pk: prevout.script_pk,
|
|
72
|
+
value: normalize_value(prevout.value),
|
|
73
|
+
};
|
|
71
74
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TxData, TxInput, TxInputTemplate, TxOutput, TxOutputTemplate, TxSpendData, TxSpendInput, TxTemplate } from "../../types/index.js";
|
|
2
2
|
export declare function assert_tx_template(txdata: unknown): asserts txdata is TxTemplate;
|
|
3
3
|
export declare function assert_has_prevouts(vin: TxInput[]): asserts vin is TxSpendInput[];
|
|
4
4
|
export declare function assert_tx_data(txdata: unknown): asserts txdata is TxData;
|
package/dist/lib/tx/validate.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as Schema from
|
|
1
|
+
import * as Schema from "../../schema/index.js";
|
|
2
2
|
export function assert_tx_template(txdata) {
|
|
3
3
|
Schema.tx.tx_template.parse(txdata);
|
|
4
4
|
}
|
|
5
5
|
export function assert_has_prevouts(vin) {
|
|
6
|
-
if (vin.some(txin => txin.prevout === null)) {
|
|
7
|
-
throw new Error(
|
|
6
|
+
if (vin.some((txin) => txin.prevout === null)) {
|
|
7
|
+
throw new Error("transaction missing prevouts");
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
export function assert_tx_data(txdata) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./parse.js";
|
|
2
|
+
export * from "./util.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./parse.js";
|
|
2
|
+
export * from "./util.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Bytes } from
|
|
2
|
-
import type { WitnessData } from
|
|
1
|
+
import { type Bytes } from "@vbyte/buff";
|
|
2
|
+
import type { WitnessData } from "../../types/index.js";
|
|
3
3
|
export declare function parse_witness(witness: Bytes[]): WitnessData;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { TAPLEAF_VERSIONS } from "../../const.js";
|
|
3
|
+
import { is_valid_script } from "../../lib/script/decode.js";
|
|
4
4
|
export function parse_witness(witness) {
|
|
5
|
-
const elems = witness.map(e => Buff.bytes(e));
|
|
6
|
-
const stack = witness.map(e => Buff.bytes(e).hex);
|
|
5
|
+
const elems = witness.map((e) => Buff.bytes(e));
|
|
6
|
+
const stack = witness.map((e) => Buff.bytes(e).hex);
|
|
7
7
|
const annex = parse_annex_data(elems);
|
|
8
8
|
if (annex !== null)
|
|
9
9
|
elems.pop();
|
|
@@ -15,14 +15,12 @@ export function parse_witness(witness) {
|
|
|
15
15
|
const script = parse_witness_script(elems, type);
|
|
16
16
|
if (script !== null)
|
|
17
17
|
elems.pop();
|
|
18
|
-
const params = elems.map(e => e.hex);
|
|
18
|
+
const params = elems.map((e) => e.hex);
|
|
19
19
|
return { annex, cblock, params, script, stack, type, version };
|
|
20
20
|
}
|
|
21
21
|
function parse_annex_data(data) {
|
|
22
|
-
|
|
23
|
-
if (data.length > 1 &&
|
|
24
|
-
elem instanceof Uint8Array &&
|
|
25
|
-
elem[0] === 0x50) {
|
|
22
|
+
const elem = data.at(-1);
|
|
23
|
+
if (data.length > 1 && elem instanceof Uint8Array && elem[0] === 0x50) {
|
|
26
24
|
return new Buff(elem).hex;
|
|
27
25
|
}
|
|
28
26
|
else {
|
|
@@ -30,7 +28,7 @@ function parse_annex_data(data) {
|
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
function parse_cblock_data(data) {
|
|
33
|
-
|
|
31
|
+
const elem = data.at(-1);
|
|
34
32
|
if (data.length > 1 &&
|
|
35
33
|
elem instanceof Uint8Array &&
|
|
36
34
|
elem.length > 32 &&
|
|
@@ -44,34 +42,37 @@ function parse_cblock_data(data) {
|
|
|
44
42
|
function parse_witness_script(elems, type) {
|
|
45
43
|
let script;
|
|
46
44
|
switch (type) {
|
|
47
|
-
case
|
|
45
|
+
case "p2ts":
|
|
48
46
|
script = elems.at(-1);
|
|
49
|
-
|
|
47
|
+
break;
|
|
48
|
+
case "p2wsh":
|
|
50
49
|
script = elems.at(-1);
|
|
50
|
+
break;
|
|
51
51
|
}
|
|
52
|
-
return
|
|
52
|
+
return script !== undefined ? new Buff(script).hex : null;
|
|
53
53
|
}
|
|
54
54
|
function parse_witness_type(elems, cblock) {
|
|
55
|
-
|
|
55
|
+
const param_0 = elems.at(0), param_1 = elems.at(1), param_x = elems.at(-1);
|
|
56
56
|
if (cblock !== null && param_x !== undefined) {
|
|
57
|
-
return
|
|
57
|
+
return "p2ts";
|
|
58
58
|
}
|
|
59
59
|
else if (elems.length === 2 &&
|
|
60
60
|
param_0 !== undefined &&
|
|
61
61
|
param_1 !== undefined &&
|
|
62
|
-
param_0.length >=
|
|
62
|
+
param_0.length >= 71 &&
|
|
63
|
+
param_0.length <= 73 &&
|
|
63
64
|
param_1.length === 33) {
|
|
64
|
-
return
|
|
65
|
+
return "p2wpkh";
|
|
65
66
|
}
|
|
66
67
|
else if (elems.length === 1 &&
|
|
67
68
|
param_0 !== undefined &&
|
|
68
|
-
param_0.length === 64) {
|
|
69
|
-
return
|
|
69
|
+
(param_0.length === 64 || param_0.length === 65)) {
|
|
70
|
+
return "p2tr";
|
|
70
71
|
}
|
|
71
72
|
else if (elems.length > 1 &&
|
|
72
73
|
param_x !== undefined &&
|
|
73
74
|
is_valid_script(param_x)) {
|
|
74
|
-
return
|
|
75
|
+
return "p2wsh";
|
|
75
76
|
}
|
|
76
77
|
else {
|
|
77
78
|
return null;
|
|
@@ -80,9 +81,9 @@ function parse_witness_type(elems, cblock) {
|
|
|
80
81
|
function parse_witness_version(type) {
|
|
81
82
|
if (type === null)
|
|
82
83
|
return null;
|
|
83
|
-
if (type.startsWith(
|
|
84
|
+
if (type.startsWith("p2w"))
|
|
84
85
|
return 0;
|
|
85
|
-
if (type.startsWith(
|
|
86
|
+
if (type.startsWith("p2t"))
|
|
86
87
|
return 1;
|
|
87
88
|
return null;
|
|
88
89
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Bytes } from
|
|
2
|
-
import type { WitnessSize } from
|
|
1
|
+
import { type Bytes } from "@vbyte/buff";
|
|
2
|
+
import type { WitnessSize } from "../../types/index.js";
|
|
3
3
|
export declare function get_witness_size(witness: Bytes[]): WitnessSize;
|
|
4
4
|
export declare function assert_witness(witness: unknown): asserts witness is Bytes[];
|
package/dist/lib/witness/util.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Buff } from
|
|
2
|
-
import { Assert } from
|
|
1
|
+
import { Buff } from "@vbyte/buff";
|
|
2
|
+
import { Assert } from "@vbyte/micro-lib";
|
|
3
3
|
const WIT_LENGTH_BYTE = 1;
|
|
4
4
|
export function get_witness_size(witness) {
|
|
5
|
-
const stack = witness.map(e => Buff.bytes(e));
|
|
5
|
+
const stack = witness.map((e) => Buff.bytes(e));
|
|
6
6
|
const size = stack.reduce((prev, next) => prev + next.length, 0);
|
|
7
7
|
const vsize = Math.ceil(WIT_LENGTH_BYTE + size / 4);
|
|
8
8
|
return { total: size, vsize };
|
|
9
9
|
}
|
|
10
10
|
export function assert_witness(witness) {
|
|
11
|
-
Assert.ok(Array.isArray(witness),
|
|
12
|
-
Assert.ok(witness.every(e => Buff.is_bytes(e)),
|
|
11
|
+
Assert.ok(Array.isArray(witness), "witness must be an array");
|
|
12
|
+
Assert.ok(witness.every((e) => Buff.is_bytes(e)), "witness must be an array of strings or bytes");
|
|
13
13
|
}
|