@vbyte/btc-dev 1.0.10 → 1.0.12
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/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/lib/sighash/segwit.d.ts +4 -1
- package/dist/lib/sighash/segwit.js +6 -6
- package/dist/lib/sighash/taproot.d.ts +7 -6
- package/dist/lib/sighash/taproot.js +24 -53
- package/dist/lib/sighash/util.d.ts +4 -2
- package/dist/lib/sighash/util.js +16 -2
- package/dist/lib/signer/sign.js +8 -5
- package/dist/lib/signer/verify.d.ts +1 -2
- package/dist/lib/signer/verify.js +1 -5
- package/dist/lib/tx/create.d.ts +7 -6
- package/dist/lib/tx/create.js +25 -27
- package/dist/lib/tx/decode.d.ts +4 -9
- package/dist/lib/tx/decode.js +16 -28
- package/dist/lib/tx/encode.d.ts +1 -1
- package/dist/lib/tx/encode.js +6 -6
- package/dist/lib/tx/parse.d.ts +3 -2
- package/dist/lib/tx/parse.js +38 -5
- package/dist/lib/tx/util.d.ts +8 -4
- package/dist/lib/tx/util.js +39 -15
- package/dist/lib/tx/validate.d.ts +4 -2
- package/dist/lib/tx/validate.js +9 -2
- package/dist/main.cjs +4049 -4269
- package/dist/main.cjs.map +1 -1
- package/dist/module.mjs +4040 -4255
- package/dist/module.mjs.map +1 -1
- package/dist/package.json +2 -2
- package/dist/schema/taproot.d.ts +2 -2
- package/dist/schema/tx.d.ts +53 -40
- package/dist/schema/tx.js +9 -6
- package/dist/script.js +8 -8
- package/dist/script.js.map +1 -1
- package/dist/types/txdata.d.ts +28 -5
- package/package.json +2 -2
- package/src/index.ts +0 -2
- package/src/lib/sighash/segwit.ts +6 -6
- package/src/lib/sighash/taproot.ts +40 -70
- package/src/lib/sighash/util.ts +25 -3
- package/src/lib/signer/sign.ts +9 -5
- package/src/lib/signer/verify.ts +1 -18
- package/src/lib/tx/create.ts +44 -36
- package/src/lib/tx/decode.ts +23 -45
- package/src/lib/tx/encode.ts +10 -9
- package/src/lib/tx/parse.ts +61 -8
- package/src/lib/tx/util.ts +57 -20
- package/src/lib/tx/validate.ts +15 -2
- package/src/schema/tx.ts +10 -6
- package/src/types/txdata.ts +32 -5
- package/dist/class/index.d.ts +0 -5
- package/dist/class/index.js +0 -5
- package/dist/class/signer.d.ts +0 -18
- package/dist/class/signer.js +0 -34
- package/dist/class/tx.d.ts +0 -51
- package/dist/class/tx.js +0 -122
- package/dist/class/txin.d.ts +0 -27
- package/dist/class/txin.js +0 -59
- package/dist/class/txout.d.ts +0 -16
- package/dist/class/txout.js +0 -31
- package/dist/class/witness.d.ts +0 -23
- package/dist/class/witness.js +0 -68
- package/src/class/index.ts +0 -5
- package/src/class/signer.ts +0 -49
- package/src/class/tx.ts +0 -175
- package/src/class/txin.ts +0 -81
- package/src/class/txout.ts +0 -50
- package/src/class/witness.ts +0 -99
package/src/lib/tx/decode.ts
CHANGED
|
@@ -1,45 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Assert }
|
|
3
|
-
import { parse_error }
|
|
4
|
-
import { COINBASE }
|
|
1
|
+
import { Stream } from '@vbyte/buff'
|
|
2
|
+
import { Assert } from '@vbyte/micro-lib/assert'
|
|
3
|
+
import { parse_error } from '@vbyte/micro-lib/util'
|
|
4
|
+
import { COINBASE } from '@/const.js'
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
TxData,
|
|
8
7
|
TxInput,
|
|
9
8
|
TxOutput,
|
|
10
9
|
TxCoinbaseInput,
|
|
11
10
|
TxVirtualInput,
|
|
12
|
-
|
|
11
|
+
TxDecodedData
|
|
13
12
|
} from '@/types/index.js'
|
|
14
13
|
|
|
15
|
-
interface TxEncoderConfig {
|
|
16
|
-
prevouts : TxOutput[]
|
|
17
|
-
segwit : boolean
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const DEFAULT_CONFIG : TxEncoderConfig = {
|
|
21
|
-
prevouts : [],
|
|
22
|
-
segwit : true
|
|
23
|
-
}
|
|
24
|
-
|
|
25
14
|
export function decode_tx (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
) :
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
// Assert the txhex is a bytes object.
|
|
32
|
-
Assert.is_bytes(txbytes, 'transaction must be hex or a byte-array')
|
|
15
|
+
txdata : string | Uint8Array,
|
|
16
|
+
use_segwit = true
|
|
17
|
+
) : TxDecodedData {
|
|
18
|
+
// Assert the txdata is a bytes object.
|
|
19
|
+
Assert.is_bytes(txdata, 'txdata must be hex or bytes')
|
|
33
20
|
// Setup a byte-stream.
|
|
34
|
-
const stream = new Stream(
|
|
21
|
+
const stream = new Stream(txdata)
|
|
35
22
|
// Parse tx version.
|
|
36
23
|
const version = read_version(stream)
|
|
37
24
|
// Check and enable any flags that are set.
|
|
38
|
-
const has_witness = (
|
|
25
|
+
const has_witness = (use_segwit)
|
|
39
26
|
? check_witness_flag(stream)
|
|
40
27
|
: false
|
|
41
28
|
// Parse our inputs and outputs.
|
|
42
|
-
const vin = read_inputs(stream
|
|
29
|
+
const vin = read_inputs(stream)
|
|
43
30
|
const vout = read_outputs(stream)
|
|
44
31
|
// If witness flag is set, parse witness data.
|
|
45
32
|
if (has_witness) {
|
|
@@ -70,28 +57,26 @@ function check_witness_flag (stream : Stream) : boolean {
|
|
|
70
57
|
return false
|
|
71
58
|
}
|
|
72
59
|
|
|
73
|
-
function read_inputs (stream : Stream
|
|
60
|
+
function read_inputs (stream : Stream) : TxInput[] {
|
|
74
61
|
const inputs = []
|
|
75
62
|
const vinCount = stream.varint()
|
|
76
63
|
for (let i = 0; i < vinCount; i++) {
|
|
77
|
-
const txinput = read_vin(stream
|
|
64
|
+
const txinput = read_vin(stream)
|
|
78
65
|
inputs.push(txinput)
|
|
79
66
|
}
|
|
80
67
|
return inputs
|
|
81
68
|
}
|
|
82
69
|
|
|
83
|
-
function read_vin (stream : Stream
|
|
70
|
+
function read_vin (stream : Stream) : TxInput {
|
|
84
71
|
const txid = stream.read(32).reverse().hex
|
|
85
72
|
const vout = stream.read(4).reverse().num
|
|
86
|
-
const script_sig =
|
|
73
|
+
const script_sig = read_payload(stream)
|
|
87
74
|
const sequence = stream.read(4).reverse().num
|
|
88
75
|
const witness : string[] = []
|
|
89
76
|
if (txid === COINBASE.TXID && vout === COINBASE.VOUT) {
|
|
90
77
|
return { coinbase : script_sig, prevout: null, script_sig : null, sequence, txid, vout, witness } as TxCoinbaseInput
|
|
91
|
-
} else if (prevout !== null) {
|
|
92
|
-
return { coinbase : null, prevout, script_sig, sequence, txid, vout, witness } as TxSpendInput
|
|
93
78
|
} else {
|
|
94
|
-
return { coinbase : null, prevout, script_sig, sequence, txid, vout, witness } as TxVirtualInput
|
|
79
|
+
return { coinbase : null, prevout: null, script_sig, sequence, txid, vout, witness } as TxVirtualInput
|
|
95
80
|
}
|
|
96
81
|
}
|
|
97
82
|
|
|
@@ -110,7 +95,7 @@ function read_outputs (stream : Stream) : TxOutput[] {
|
|
|
110
95
|
|
|
111
96
|
function read_vout (stream : Stream) : TxOutput {
|
|
112
97
|
const value = stream.read(8).reverse().big
|
|
113
|
-
const script_pk =
|
|
98
|
+
const script_pk = read_payload(stream)
|
|
114
99
|
Assert.exists(script_pk, 'failed to decode script_pk')
|
|
115
100
|
return { value, script_pk }
|
|
116
101
|
}
|
|
@@ -119,7 +104,7 @@ function read_witness (stream : Stream) : string[] {
|
|
|
119
104
|
const stack = []
|
|
120
105
|
const count = stream.varint()
|
|
121
106
|
for (let i = 0; i < count; i++) {
|
|
122
|
-
const element =
|
|
107
|
+
const element = read_payload(stream)
|
|
123
108
|
if (element === null) {
|
|
124
109
|
throw new Error('failed to decode witness element: ' + i)
|
|
125
110
|
}
|
|
@@ -128,16 +113,9 @@ function read_witness (stream : Stream) : string[] {
|
|
|
128
113
|
return stack
|
|
129
114
|
}
|
|
130
115
|
|
|
131
|
-
export function
|
|
132
|
-
stream
|
|
133
|
-
|
|
134
|
-
) : string | null {
|
|
135
|
-
const size = (varint === true)
|
|
136
|
-
? stream.varint('le')
|
|
137
|
-
: stream.size
|
|
138
|
-
return size > 0
|
|
139
|
-
? stream.read(size).hex
|
|
140
|
-
: null
|
|
116
|
+
export function read_payload (stream : Stream) : string | null {
|
|
117
|
+
const size = stream.varint('le')
|
|
118
|
+
return (size > 0) ? stream.read(size).hex : null
|
|
141
119
|
}
|
|
142
120
|
|
|
143
121
|
function read_locktime (stream : Stream) : number {
|
package/src/lib/tx/encode.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Buff }
|
|
2
|
-
import { Assert }
|
|
3
|
-
import {
|
|
4
|
-
import { COINBASE }
|
|
1
|
+
import { Buff } from '@vbyte/buff'
|
|
2
|
+
import { Assert } from '@vbyte/micro-lib'
|
|
3
|
+
import { assert_tx_data } from './validate.js'
|
|
4
|
+
import { COINBASE } from '@/const.js'
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
TxInput,
|
|
@@ -11,15 +11,16 @@ import {
|
|
|
11
11
|
|
|
12
12
|
export function encode_tx (
|
|
13
13
|
txdata : TxData,
|
|
14
|
-
|
|
14
|
+
use_segwit = true
|
|
15
15
|
) : Buff {
|
|
16
|
-
|
|
16
|
+
// Assert the txdata is a valid tx data object.
|
|
17
|
+
assert_tx_data(txdata)
|
|
17
18
|
// Unpack the transaction data.
|
|
18
|
-
const { version, vin, vout, locktime } =
|
|
19
|
+
const { version, vin, vout, locktime } = txdata
|
|
19
20
|
// Create a buffer for the transaction.
|
|
20
21
|
const buffer : Buff[] = [ encode_tx_version(version) ]
|
|
21
22
|
// If the transaction is a segwit transaction,
|
|
22
|
-
if (
|
|
23
|
+
if (use_segwit) {
|
|
23
24
|
// Add the segwit marker to the buffer.
|
|
24
25
|
buffer.push(Buff.hex('0001'))
|
|
25
26
|
}
|
|
@@ -28,7 +29,7 @@ export function encode_tx (
|
|
|
28
29
|
// Add the outputs to the buffer.
|
|
29
30
|
buffer.push(encode_tx_outputs(vout))
|
|
30
31
|
// If the transaction is a segwit transaction,
|
|
31
|
-
if (
|
|
32
|
+
if (use_segwit) {
|
|
32
33
|
// For each input in the transaction,
|
|
33
34
|
for (const input of vin) {
|
|
34
35
|
// Add the witness data to the buffer.
|
package/src/lib/tx/parse.ts
CHANGED
|
@@ -1,16 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { assert_tx_template }
|
|
1
|
+
import { Assert } from '@vbyte/micro-lib/assert'
|
|
2
|
+
import { decode_tx } from './decode.js'
|
|
3
|
+
import { assert_tx_template } from './validate.js'
|
|
4
|
+
import { create_tx, create_tx_output } from './create.js'
|
|
4
5
|
|
|
5
|
-
import type { TxData } from '@/types/index.js'
|
|
6
|
+
import type { TxData, TxOutputTemplate } from '@/types/index.js'
|
|
6
7
|
|
|
7
8
|
export function parse_tx (
|
|
8
|
-
txdata
|
|
9
|
+
txdata : unknown,
|
|
10
|
+
prevouts? : TxOutputTemplate[]
|
|
9
11
|
) : TxData {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// Define the tx variable.
|
|
13
|
+
let tx : TxData
|
|
14
|
+
// If the txdata is a string or Uint8Array,
|
|
15
|
+
if (typeof txdata === 'string' || txdata instanceof Uint8Array) {
|
|
16
|
+
// Decode the tx.
|
|
17
|
+
tx = decode_tx(txdata)
|
|
12
18
|
} else {
|
|
19
|
+
// Assert the txdata is a valid tx template.
|
|
13
20
|
assert_tx_template(txdata)
|
|
14
|
-
|
|
21
|
+
// Create the tx.
|
|
22
|
+
tx = create_tx(txdata)
|
|
23
|
+
}
|
|
24
|
+
// If the prevouts are provided,
|
|
25
|
+
if (prevouts) {
|
|
26
|
+
// Assert the prevouts are a non-empty array.
|
|
27
|
+
Assert.has_items(prevouts, 'prevouts must be a non-empty array')
|
|
28
|
+
// Iterate over the inputs.
|
|
29
|
+
for (const [ idx, vin ] of tx.vin.entries()) {
|
|
30
|
+
// Get the prevout.
|
|
31
|
+
const prevout = prevouts.at(idx)
|
|
32
|
+
// Assert the prevout exists.
|
|
33
|
+
Assert.exists(prevout, 'prevout not found for input index: ' + idx)
|
|
34
|
+
// Create the prevout.
|
|
35
|
+
vin.prevout = create_tx_output(prevout)
|
|
36
|
+
}
|
|
15
37
|
}
|
|
38
|
+
// Return the tx.
|
|
39
|
+
return tx
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function serialize_tx (
|
|
43
|
+
txdata : unknown
|
|
44
|
+
) : Record<string, unknown> {
|
|
45
|
+
const tx = parse_tx(txdata)
|
|
46
|
+
const version = tx.version
|
|
47
|
+
const locktime = tx.locktime
|
|
48
|
+
|
|
49
|
+
const vin : Record<string, unknown>[] = []
|
|
50
|
+
const vout : Record<string, unknown>[] = []
|
|
51
|
+
|
|
52
|
+
for (const e of tx.vin) {
|
|
53
|
+
if (e.prevout !== null) {
|
|
54
|
+
vin.push({
|
|
55
|
+
script_pk : e.prevout.script_pk,
|
|
56
|
+
value : Number(e.prevout.value)
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const e of tx.vout) {
|
|
62
|
+
vout.push({
|
|
63
|
+
script_pk : e.script_pk,
|
|
64
|
+
value : Number(e.value)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { version, locktime, vin, vout }
|
|
16
69
|
}
|
package/src/lib/tx/util.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
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 { encode_tx } from './encode.js'
|
|
6
|
+
import { assert_tx_template } from './validate.js'
|
|
7
|
+
|
|
8
|
+
import { DEFAULT, LOCK_SCRIPT_REGEX } from '@/const.js'
|
|
5
9
|
|
|
6
10
|
import type {
|
|
7
11
|
TxData,
|
|
8
12
|
TxOutput,
|
|
9
13
|
TxOutputInfo,
|
|
14
|
+
TxOutputTemplate,
|
|
10
15
|
TxOutputType,
|
|
11
16
|
TxValue,
|
|
12
17
|
WitnessVersion
|
|
@@ -37,37 +42,69 @@ export function get_vout_version (
|
|
|
37
42
|
) : WitnessVersion {
|
|
38
43
|
const wit_ver = script.slice(0, 4)
|
|
39
44
|
switch (wit_ver) {
|
|
40
|
-
case '0014':
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return 1
|
|
44
|
-
default:
|
|
45
|
-
return null
|
|
45
|
+
case '0014' : return 0
|
|
46
|
+
case '5120' : return 1
|
|
47
|
+
default : return null
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
export function get_txid (
|
|
50
|
-
txdata :
|
|
52
|
+
txdata : TxData
|
|
51
53
|
) : string {
|
|
52
|
-
|
|
53
|
-
const data = encode_tx(
|
|
54
|
+
assert_tx_template(txdata)
|
|
55
|
+
const data = encode_tx(txdata, false)
|
|
54
56
|
return hash256(data).reverse().hex
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export function get_txhash (
|
|
58
|
-
txdata :
|
|
60
|
+
txdata : TxData
|
|
59
61
|
) : string {
|
|
60
|
-
|
|
61
|
-
const data = encode_tx(
|
|
62
|
+
assert_tx_template(txdata)
|
|
63
|
+
const data = encode_tx(txdata, true)
|
|
62
64
|
return hash256(data).reverse().hex
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
export function get_tx_value (
|
|
66
|
-
txdata :
|
|
68
|
+
txdata : TxData
|
|
67
69
|
) : TxValue {
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
const vout = tx.vout.reduce((acc, txout) => acc + txout.value, 0n)
|
|
70
|
+
const vin = txdata.vin.reduce((acc, txin) => acc + (txin.prevout?.value ?? 0n), 0n)
|
|
71
|
+
const vout = txdata.vout.reduce((acc, txout) => acc + txout.value, 0n)
|
|
71
72
|
const fees = (vin > vout) ? (vin - vout) : 0n
|
|
72
73
|
return { fees, vin, vout }
|
|
73
74
|
}
|
|
75
|
+
|
|
76
|
+
export function get_prevouts (txdata : TxData) : TxOutput[] {
|
|
77
|
+
// Assert the structure of the transaction data is valid.
|
|
78
|
+
assert_tx_template(txdata)
|
|
79
|
+
// Collect the prevouts from the transaction.
|
|
80
|
+
const prevouts = txdata.vin.map(e => e.prevout)
|
|
81
|
+
// Assert that all the prevouts are defined.
|
|
82
|
+
Assert.ok(prevouts.every(e => e !== null), 'prevouts missing from tx')
|
|
83
|
+
// Return the array of prevouts.
|
|
84
|
+
return prevouts
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function normalize_sequence (sequence? : number | string | null) : number {
|
|
88
|
+
// If sequence is not defined, return a default sequence value.
|
|
89
|
+
if (!Test.exists(sequence)) return DEFAULT.SEQUENCE
|
|
90
|
+
// If sequence is a hex string, decode it and return the number value.
|
|
91
|
+
if (Test.is_hex(sequence)) return Buff.hex(sequence as string, 4).reverse().num
|
|
92
|
+
// If sequence is a valid unsigned integer, return the value.
|
|
93
|
+
if (Test.is_uint(sequence)) return sequence
|
|
94
|
+
// Else, throw an error.
|
|
95
|
+
throw new Error('invalid sequence value: ' + String(sequence))
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function normalize_value (value : number | bigint) : bigint {
|
|
99
|
+
// If value is a unsigned integer, return it as a bigint.
|
|
100
|
+
if (Test.is_uint(value)) return BigInt(value)
|
|
101
|
+
// If value is a bigint, return it as-is.
|
|
102
|
+
if (typeof value === 'bigint') return value
|
|
103
|
+
// Else, throw an error.
|
|
104
|
+
throw new TypeError('invalid output value: ' + String(value))
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function normalize_prevout (prevout : TxOutputTemplate) : TxOutput {
|
|
108
|
+
// Return the output with a normalized value.
|
|
109
|
+
return { script_pk: prevout.script_pk, value: normalize_value(prevout.value) }
|
|
110
|
+
}
|
package/src/lib/tx/validate.ts
CHANGED
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
TxInputTemplate,
|
|
8
8
|
TxOutput,
|
|
9
9
|
TxTemplate,
|
|
10
|
+
TxOutputTemplate,
|
|
11
|
+
TxSpendData,
|
|
10
12
|
} from '@/types/index.js'
|
|
11
13
|
|
|
12
14
|
export function assert_tx_template (txdata : unknown) : asserts txdata is TxTemplate {
|
|
@@ -23,6 +25,13 @@ export function assert_tx_data (txdata : unknown) : asserts txdata is TxData {
|
|
|
23
25
|
Schema.tx.tx_data.parse(txdata)
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
export function assert_tx_spend_data (txdata : unknown) : asserts txdata is TxSpendData {
|
|
29
|
+
// Assert the txdata is a valid tx data object.
|
|
30
|
+
assert_tx_data(txdata)
|
|
31
|
+
// Assert the txdata has prevouts.
|
|
32
|
+
assert_has_prevouts(txdata.vin)
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
export function assert_tx_input (tx_input : unknown) : asserts tx_input is TxInput {
|
|
27
36
|
Schema.tx.tx_input.parse(tx_input)
|
|
28
37
|
}
|
|
@@ -31,6 +40,10 @@ export function assert_tx_output (tx_output : unknown) : asserts tx_output is Tx
|
|
|
31
40
|
Schema.tx.tx_output.parse(tx_output)
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
export function assert_vin_template (
|
|
35
|
-
Schema.tx.vin_template.parse(
|
|
43
|
+
export function assert_vin_template (vin : unknown) : asserts vin is TxInputTemplate {
|
|
44
|
+
Schema.tx.vin_template.parse(vin)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function assert_vout_template (vout : unknown) : asserts vout is TxOutputTemplate {
|
|
48
|
+
Schema.tx.vout_template.parse(vout)
|
|
36
49
|
}
|
package/src/schema/tx.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { hex, hex32, uint } from '@vbyte/micro-lib/schema'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
const sats = z.bigint().positive().max(2_100_000_000_000_000n)
|
|
6
6
|
|
|
7
7
|
export const tx_output = z.object({
|
|
8
8
|
value : sats,
|
|
@@ -26,17 +26,21 @@ export const tx_data = z.object({
|
|
|
26
26
|
locktime : uint,
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
+
export const vout_template = tx_output.extend({
|
|
30
|
+
value : z.union([ uint, sats ])
|
|
31
|
+
})
|
|
32
|
+
|
|
29
33
|
export const vin_template = tx_input.extend({
|
|
30
34
|
coinbase : hex.nullable().optional(),
|
|
31
|
-
prevout :
|
|
35
|
+
prevout : vout_template.nullable().optional(),
|
|
32
36
|
script_sig : hex.nullable().optional(),
|
|
33
|
-
sequence : uint.optional(),
|
|
37
|
+
sequence : z.union([ hex, uint ]).optional(),
|
|
34
38
|
witness : z.array(hex).optional(),
|
|
35
39
|
})
|
|
36
40
|
|
|
37
41
|
export const tx_template = z.object({
|
|
38
|
-
version : uint.
|
|
42
|
+
version : uint.default(1),
|
|
39
43
|
vin : z.array(vin_template).default([]),
|
|
40
|
-
vout : z.array(
|
|
44
|
+
vout : z.array(vout_template).default([]),
|
|
41
45
|
locktime : uint.optional(),
|
|
42
46
|
})
|
package/src/types/txdata.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface TxOutpoint {
|
|
|
5
5
|
vout : number
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface TxInputConfig extends TxOutpoint {
|
|
9
9
|
coinbase? : string | null
|
|
10
10
|
prevout? : TxOutput | null
|
|
11
11
|
script_sig? : string | null
|
|
@@ -13,6 +13,14 @@ export interface TxInputTemplate extends TxOutpoint {
|
|
|
13
13
|
witness? : string[]
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export interface TxInputTemplate extends TxOutpoint {
|
|
17
|
+
coinbase : string | null
|
|
18
|
+
prevout : TxOutput | null
|
|
19
|
+
script_sig : string | null
|
|
20
|
+
sequence : number
|
|
21
|
+
witness : string[]
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
export interface TxCoinbaseInput extends TxOutpoint {
|
|
17
25
|
coinbase : string
|
|
18
26
|
prevout : null
|
|
@@ -33,16 +41,21 @@ export interface TxSpendInput extends TxVirtualInput {
|
|
|
33
41
|
prevout : TxOutput
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
export interface TxOutputTemplate {
|
|
45
|
+
script_pk : string
|
|
46
|
+
value : number | bigint
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
export interface TxOutput {
|
|
37
50
|
script_pk : string
|
|
38
51
|
value : bigint
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
export interface TxTemplate {
|
|
42
|
-
locktime
|
|
43
|
-
vin
|
|
44
|
-
vout
|
|
45
|
-
version
|
|
55
|
+
locktime : number
|
|
56
|
+
vin : TxInputTemplate[]
|
|
57
|
+
vout : TxOutputTemplate[]
|
|
58
|
+
version : number
|
|
46
59
|
}
|
|
47
60
|
|
|
48
61
|
export interface TxData {
|
|
@@ -52,6 +65,20 @@ export interface TxData {
|
|
|
52
65
|
version : number
|
|
53
66
|
}
|
|
54
67
|
|
|
68
|
+
export interface TxDecodedData {
|
|
69
|
+
locktime : number
|
|
70
|
+
vin : (TxCoinbaseInput | TxVirtualInput)[]
|
|
71
|
+
vout : TxOutput[]
|
|
72
|
+
version : number
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface TxSpendData {
|
|
76
|
+
locktime : number
|
|
77
|
+
vin : TxSpendInput[]
|
|
78
|
+
vout : TxOutput[]
|
|
79
|
+
version : number
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
export interface TxSize {
|
|
56
83
|
base : number
|
|
57
84
|
total : number
|
package/dist/class/index.d.ts
DELETED
package/dist/class/index.js
DELETED
package/dist/class/signer.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { Buff, Bytes } from '@vbyte/buff';
|
|
2
|
-
import type { SigHashOptions, TxData } from '../types/index.js';
|
|
3
|
-
export declare class TxSigner {
|
|
4
|
-
private readonly _seckey;
|
|
5
|
-
constructor(seckey: Bytes);
|
|
6
|
-
get pubkey(): {
|
|
7
|
-
segwit: Buff;
|
|
8
|
-
taproot: Buff;
|
|
9
|
-
};
|
|
10
|
-
get sign_msg(): {
|
|
11
|
-
ecdsa: (msg: Bytes) => Buff;
|
|
12
|
-
bip340: (msg: Bytes) => Buff;
|
|
13
|
-
};
|
|
14
|
-
get sign_tx(): {
|
|
15
|
-
segwit: (tx: TxData, options: SigHashOptions) => string;
|
|
16
|
-
taproot: (tx: TxData, options: SigHashOptions) => string;
|
|
17
|
-
};
|
|
18
|
-
}
|
package/dist/class/signer.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { Buff } from '@vbyte/buff';
|
|
2
|
-
import { Assert, ECC } from '@vbyte/micro-lib';
|
|
3
|
-
import { sign_segwit_tx, sign_taproot_tx } from '../lib/signer/sign.js';
|
|
4
|
-
export class TxSigner {
|
|
5
|
-
constructor(seckey) {
|
|
6
|
-
Assert.ok(Buff.is_bytes(seckey), 'seckey must be a string or bytes');
|
|
7
|
-
Assert.size(seckey, 32, 'seckey must be 32 bytes');
|
|
8
|
-
this._seckey = Buff.bytes(seckey).hex;
|
|
9
|
-
}
|
|
10
|
-
get pubkey() {
|
|
11
|
-
return {
|
|
12
|
-
segwit: ECC.get_pubkey(this._seckey, 'ecdsa'),
|
|
13
|
-
taproot: ECC.get_pubkey(this._seckey, 'bip340')
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
get sign_msg() {
|
|
17
|
-
return {
|
|
18
|
-
ecdsa: (msg) => {
|
|
19
|
-
const bytes = Buff.bytes(msg);
|
|
20
|
-
return ECC.sign_ecdsa(this._seckey, bytes);
|
|
21
|
-
},
|
|
22
|
-
bip340: (msg) => {
|
|
23
|
-
const bytes = Buff.bytes(msg);
|
|
24
|
-
return ECC.sign_bip340(this._seckey, bytes);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
get sign_tx() {
|
|
29
|
-
return {
|
|
30
|
-
segwit: (tx, options) => sign_segwit_tx(this._seckey, tx, options),
|
|
31
|
-
taproot: (tx, options) => sign_taproot_tx(this._seckey, tx, options)
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
}
|
package/dist/class/tx.d.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { TransactionInput } from './txin.js';
|
|
2
|
-
import { TransactionOutput } from './txout.js';
|
|
3
|
-
import type { TxData, TxTemplate, TxOutput, TxSize, TxValue, TxInputTemplate } from '../types/index.js';
|
|
4
|
-
export declare class Transaction {
|
|
5
|
-
private readonly _tx;
|
|
6
|
-
private _size;
|
|
7
|
-
private _hash;
|
|
8
|
-
private _txid;
|
|
9
|
-
private _value;
|
|
10
|
-
private _vin;
|
|
11
|
-
private _vout;
|
|
12
|
-
constructor(txdata?: string | TxData | TxTemplate);
|
|
13
|
-
get data(): TxData;
|
|
14
|
-
get hash(): string;
|
|
15
|
-
get locktime(): {
|
|
16
|
-
hex: string;
|
|
17
|
-
data: import("../types/index.js").LocktimeData | null;
|
|
18
|
-
value: number;
|
|
19
|
-
};
|
|
20
|
-
get return(): TxOutput | null;
|
|
21
|
-
get size(): TxSize & {
|
|
22
|
-
segwit: number;
|
|
23
|
-
};
|
|
24
|
-
get spends(): TransactionOutput[];
|
|
25
|
-
get txid(): string;
|
|
26
|
-
get value(): TxValue;
|
|
27
|
-
get version(): number;
|
|
28
|
-
get vin(): TransactionInput[];
|
|
29
|
-
get vout(): TransactionOutput[];
|
|
30
|
-
add_vin(tx_input: TxInputTemplate): void;
|
|
31
|
-
add_vout(tx_output: TxOutput): void;
|
|
32
|
-
insert_vin(index: number, tx_input: TxInputTemplate): void;
|
|
33
|
-
insert_vout(index: number, tx_output: TxOutput): void;
|
|
34
|
-
remove_vin(index: number): void;
|
|
35
|
-
remove_vout(index: number): void;
|
|
36
|
-
_get_size(): {
|
|
37
|
-
segwit: number;
|
|
38
|
-
vin: number;
|
|
39
|
-
vout: number;
|
|
40
|
-
witness: number;
|
|
41
|
-
base: number;
|
|
42
|
-
total: number;
|
|
43
|
-
vsize: number;
|
|
44
|
-
weight: number;
|
|
45
|
-
};
|
|
46
|
-
_update_tx(): void;
|
|
47
|
-
_update_vin(): void;
|
|
48
|
-
_update_vout(): void;
|
|
49
|
-
toJSON(): TxData;
|
|
50
|
-
toString(): string;
|
|
51
|
-
}
|