@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.
Files changed (174) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +260 -3
  3. package/dist/const.d.ts +3 -0
  4. package/dist/const.js +23 -22
  5. package/dist/index.d.ts +11 -11
  6. package/dist/index.js +10 -10
  7. package/dist/lib/address/api.d.ts +2 -2
  8. package/dist/lib/address/api.js +12 -12
  9. package/dist/lib/address/encode.d.ts +1 -1
  10. package/dist/lib/address/encode.js +24 -24
  11. package/dist/lib/address/index.d.ts +6 -6
  12. package/dist/lib/address/index.js +6 -6
  13. package/dist/lib/address/p2pkh.d.ts +2 -2
  14. package/dist/lib/address/p2pkh.js +14 -14
  15. package/dist/lib/address/p2sh.d.ts +2 -2
  16. package/dist/lib/address/p2sh.js +13 -13
  17. package/dist/lib/address/p2tr.d.ts +2 -2
  18. package/dist/lib/address/p2tr.js +13 -13
  19. package/dist/lib/address/p2wpkh.d.ts +2 -2
  20. package/dist/lib/address/p2wpkh.js +14 -14
  21. package/dist/lib/address/p2wsh.d.ts +2 -2
  22. package/dist/lib/address/p2wsh.js +13 -13
  23. package/dist/lib/address/script.d.ts +1 -1
  24. package/dist/lib/address/script.js +16 -16
  25. package/dist/lib/address/util.d.ts +1 -1
  26. package/dist/lib/address/util.js +22 -22
  27. package/dist/lib/meta/index.d.ts +4 -4
  28. package/dist/lib/meta/index.js +4 -4
  29. package/dist/lib/meta/locktime.d.ts +1 -1
  30. package/dist/lib/meta/locktime.js +12 -12
  31. package/dist/lib/meta/ref.js +9 -6
  32. package/dist/lib/meta/scribe.d.ts +2 -2
  33. package/dist/lib/meta/scribe.js +48 -53
  34. package/dist/lib/meta/sequence.d.ts +1 -1
  35. package/dist/lib/meta/sequence.js +16 -15
  36. package/dist/lib/script/decode.d.ts +2 -2
  37. package/dist/lib/script/decode.js +50 -15
  38. package/dist/lib/script/encode.d.ts +1 -1
  39. package/dist/lib/script/encode.js +20 -16
  40. package/dist/lib/script/index.d.ts +5 -13
  41. package/dist/lib/script/index.js +5 -14
  42. package/dist/lib/script/lock.d.ts +2 -2
  43. package/dist/lib/script/lock.js +15 -12
  44. package/dist/lib/script/util.js +4 -4
  45. package/dist/lib/script/words.js +129 -129
  46. package/dist/lib/sighash/index.d.ts +3 -3
  47. package/dist/lib/sighash/index.js +3 -3
  48. package/dist/lib/sighash/segwit.d.ts +2 -2
  49. package/dist/lib/sighash/segwit.js +15 -14
  50. package/dist/lib/sighash/taproot.d.ts +2 -2
  51. package/dist/lib/sighash/taproot.js +24 -23
  52. package/dist/lib/sighash/util.d.ts +2 -2
  53. package/dist/lib/sighash/util.js +7 -7
  54. package/dist/lib/signer/index.d.ts +2 -2
  55. package/dist/lib/signer/index.js +2 -2
  56. package/dist/lib/signer/sign.d.ts +1 -1
  57. package/dist/lib/signer/sign.js +42 -7
  58. package/dist/lib/signer/verify.d.ts +17 -3
  59. package/dist/lib/signer/verify.js +233 -3
  60. package/dist/lib/taproot/cblock.d.ts +1 -1
  61. package/dist/lib/taproot/cblock.js +14 -16
  62. package/dist/lib/taproot/encode.d.ts +1 -1
  63. package/dist/lib/taproot/encode.js +7 -7
  64. package/dist/lib/taproot/index.d.ts +4 -4
  65. package/dist/lib/taproot/index.js +4 -4
  66. package/dist/lib/taproot/parse.d.ts +1 -1
  67. package/dist/lib/taproot/parse.js +12 -14
  68. package/dist/lib/taproot/tree.d.ts +2 -2
  69. package/dist/lib/taproot/tree.js +11 -7
  70. package/dist/lib/tx/create.d.ts +1 -1
  71. package/dist/lib/tx/create.js +28 -12
  72. package/dist/lib/tx/decode.d.ts +2 -2
  73. package/dist/lib/tx/decode.js +50 -17
  74. package/dist/lib/tx/encode.d.ts +2 -2
  75. package/dist/lib/tx/encode.js +13 -16
  76. package/dist/lib/tx/index.d.ts +7 -7
  77. package/dist/lib/tx/index.js +7 -7
  78. package/dist/lib/tx/parse.d.ts +1 -1
  79. package/dist/lib/tx/parse.js +9 -9
  80. package/dist/lib/tx/size.d.ts +2 -2
  81. package/dist/lib/tx/size.js +9 -9
  82. package/dist/lib/tx/util.d.ts +2 -2
  83. package/dist/lib/tx/util.js +23 -20
  84. package/dist/lib/tx/validate.d.ts +1 -1
  85. package/dist/lib/tx/validate.js +3 -3
  86. package/dist/lib/witness/index.d.ts +2 -2
  87. package/dist/lib/witness/index.js +2 -2
  88. package/dist/lib/witness/parse.d.ts +2 -2
  89. package/dist/lib/witness/parse.js +24 -23
  90. package/dist/lib/witness/util.d.ts +2 -2
  91. package/dist/lib/witness/util.js +5 -5
  92. package/dist/main.cjs +2308 -1005
  93. package/dist/main.cjs.map +1 -1
  94. package/dist/module.mjs +2308 -1005
  95. package/dist/module.mjs.map +1 -1
  96. package/dist/package.json +20 -17
  97. package/dist/schema/base.d.ts +1 -1
  98. package/dist/schema/base.js +17 -13
  99. package/dist/schema/index.d.ts +2 -2
  100. package/dist/schema/index.js +2 -2
  101. package/dist/schema/taproot.d.ts +1 -1
  102. package/dist/schema/taproot.js +2 -2
  103. package/dist/schema/tx.d.ts +1 -1
  104. package/dist/schema/tx.js +4 -4
  105. package/dist/script.js +8 -8
  106. package/dist/script.js.map +1 -1
  107. package/dist/types/address.d.ts +4 -4
  108. package/dist/types/index.d.ts +8 -8
  109. package/dist/types/index.js +8 -8
  110. package/dist/types/meta.d.ts +4 -4
  111. package/dist/types/psbt.d.ts +2 -2
  112. package/dist/types/script.d.ts +2 -2
  113. package/dist/types/sighash.d.ts +2 -2
  114. package/dist/types/witness.d.ts +5 -5
  115. package/package.json +20 -17
  116. package/src/const.ts +0 -61
  117. package/src/index.ts +0 -13
  118. package/src/lib/address/api.ts +0 -50
  119. package/src/lib/address/encode.ts +0 -183
  120. package/src/lib/address/index.ts +0 -7
  121. package/src/lib/address/p2pkh.ts +0 -94
  122. package/src/lib/address/p2sh.ts +0 -96
  123. package/src/lib/address/p2tr.ts +0 -91
  124. package/src/lib/address/p2wpkh.ts +0 -94
  125. package/src/lib/address/p2wsh.ts +0 -92
  126. package/src/lib/address/script.ts +0 -63
  127. package/src/lib/address/util.ts +0 -87
  128. package/src/lib/meta/index.ts +0 -4
  129. package/src/lib/meta/locktime.ts +0 -57
  130. package/src/lib/meta/ref.ts +0 -107
  131. package/src/lib/meta/scribe.ts +0 -256
  132. package/src/lib/meta/sequence.ts +0 -146
  133. package/src/lib/script/decode.ts +0 -85
  134. package/src/lib/script/encode.ts +0 -129
  135. package/src/lib/script/index.ts +0 -20
  136. package/src/lib/script/lock.ts +0 -73
  137. package/src/lib/script/util.ts +0 -78
  138. package/src/lib/script/words.ts +0 -182
  139. package/src/lib/sighash/index.ts +0 -3
  140. package/src/lib/sighash/segwit.ts +0 -152
  141. package/src/lib/sighash/taproot.ts +0 -206
  142. package/src/lib/sighash/util.ts +0 -51
  143. package/src/lib/signer/index.ts +0 -2
  144. package/src/lib/signer/sign.ts +0 -39
  145. package/src/lib/signer/verify.ts +0 -88
  146. package/src/lib/taproot/cblock.ts +0 -96
  147. package/src/lib/taproot/encode.ts +0 -49
  148. package/src/lib/taproot/index.ts +0 -4
  149. package/src/lib/taproot/parse.ts +0 -65
  150. package/src/lib/taproot/tree.ts +0 -94
  151. package/src/lib/tx/create.ts +0 -90
  152. package/src/lib/tx/decode.ts +0 -123
  153. package/src/lib/tx/encode.ts +0 -155
  154. package/src/lib/tx/index.ts +0 -7
  155. package/src/lib/tx/parse.ts +0 -69
  156. package/src/lib/tx/size.ts +0 -68
  157. package/src/lib/tx/util.ts +0 -111
  158. package/src/lib/tx/validate.ts +0 -49
  159. package/src/lib/witness/index.ts +0 -2
  160. package/src/lib/witness/parse.ts +0 -127
  161. package/src/lib/witness/util.ts +0 -18
  162. package/src/schema/base.ts +0 -57
  163. package/src/schema/index.ts +0 -2
  164. package/src/schema/taproot.ts +0 -12
  165. package/src/schema/tx.ts +0 -48
  166. package/src/types/address.ts +0 -35
  167. package/src/types/index.ts +0 -8
  168. package/src/types/meta.ts +0 -48
  169. package/src/types/psbt.ts +0 -15
  170. package/src/types/script.ts +0 -18
  171. package/src/types/sighash.ts +0 -16
  172. package/src/types/taproot.ts +0 -41
  173. package/src/types/txdata.ts +0 -85
  174. package/src/types/witness.ts +0 -42
@@ -1,155 +0,0 @@
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
-
6
- import {
7
- TxInput,
8
- TxOutput,
9
- TxData
10
- } from '@/types/index.js'
11
-
12
- export function encode_tx (
13
- txdata : TxData,
14
- use_segwit = true
15
- ) : Buff {
16
- // Assert the txdata is a valid tx data object.
17
- assert_tx_data(txdata)
18
- // Unpack the transaction data.
19
- const { version, vin, vout, locktime } = txdata
20
- // Create a buffer for the transaction.
21
- const buffer : Buff[] = [ encode_tx_version(version) ]
22
- // If the transaction is a segwit transaction,
23
- if (use_segwit) {
24
- // Add the segwit marker to the buffer.
25
- buffer.push(Buff.hex('0001'))
26
- }
27
- // Add the inputs to the buffer.
28
- buffer.push(encode_tx_inputs(vin))
29
- // Add the outputs to the buffer.
30
- buffer.push(encode_tx_outputs(vout))
31
- // If the transaction is a segwit transaction,
32
- if (use_segwit) {
33
- // For each input in the transaction,
34
- for (const input of vin) {
35
- // Add the witness data to the buffer.
36
- buffer.push(encode_vin_witness(input.witness))
37
- }
38
- }
39
- // Add the locktime to the buffer.
40
- buffer.push(encode_tx_locktime(locktime))
41
- // Return the buffer as a single payload.
42
- return Buff.join(buffer)
43
- }
44
-
45
- export function encode_tx_version (num : number) : Buff {
46
- // Encode the transaction version as a 4-byte little-endian number.
47
- return Buff.num(num, 4).reverse()
48
- }
49
-
50
- export function encode_txin_txid (txid : string) : Buff {
51
- // Encode the transaction ID as a 32-byte little-endian number.
52
- return Buff.hex(txid, 32).reverse()
53
- }
54
-
55
- export function encode_txin_vout (vout : number) : Buff {
56
- // Encode the output index as a 4-byte little-endian number.
57
- return Buff.num(vout, 4).reverse()
58
- }
59
-
60
- export function encode_txin_sequence (sequence : number) : Buff {
61
- // Encode the sequence number as a 4-byte little-endian number.
62
- return Buff.num(sequence, 4).reverse()
63
- }
64
-
65
- export function encode_tx_inputs (vin : TxInput[]) : Buff {
66
- // Create a buffer for the inputs, starting with the array length.
67
- const raw : Buff[] = [ Buff.varint(vin.length, 'le') ]
68
- // For each input in the array,
69
- for (const input of vin) {
70
- // Encode the input, and add it to the buffer.
71
- raw.push(encode_vin(input))
72
- }
73
- // Return the buffer as a single payload.
74
- return Buff.join(raw)
75
- }
76
-
77
- export function encode_vin (txin : TxInput) : Buff {
78
- // If the input is a coinbase,
79
- if (txin.coinbase !== null) {
80
- // Encode and return the coinbase as a single payload.
81
- return Buff.join([
82
- encode_txin_txid(COINBASE.TXID),
83
- encode_txin_vout(COINBASE.VOUT),
84
- encode_script_data(txin.coinbase),
85
- encode_txin_sequence(txin.sequence)
86
- ])
87
- } else {
88
- // Encode and return the input as a single payload.
89
- return Buff.join([
90
- encode_txin_txid(txin.txid),
91
- encode_txin_vout(txin.vout),
92
- encode_script_data(txin.script_sig),
93
- encode_txin_sequence(txin.sequence)
94
- ])
95
- }
96
- }
97
-
98
- export function encode_vout_value (value : bigint) : Buff {
99
- // Encode the value as an 8-byte little-endian number.
100
- return Buff.big(value, 8).reverse()
101
- }
102
-
103
- export function encode_tx_outputs (vout : TxOutput[]) : Buff {
104
- // Create a buffer for the outputs, starting with the array length.
105
- const buffer : Buff[] = [ Buff.varint(vout.length, 'le') ]
106
- // For each output in the array,
107
- for (const output of vout) {
108
- // Encode the output, and add it to the buffer.
109
- buffer.push(encode_tx_vout(output))
110
- }
111
- // Return the buffer as a single payload.
112
- return Buff.join(buffer)
113
- }
114
-
115
- export function encode_tx_vout (txout : TxOutput) : Buff {
116
- // Get the value and script pubkey from the output.
117
- const { value, script_pk } = txout
118
- // Return the data encoded as a single payload.
119
- return Buff.join([
120
- encode_vout_value(value),
121
- encode_script_data(script_pk)
122
- ])
123
- }
124
-
125
- export function encode_vin_witness (data : string[]) : Buff {
126
- // Create a buffer for the witness data, starting with the array length.
127
- const buffer : Buff[] = [ Buff.varint(data.length) ]
128
- // For each parameter in the witness array,
129
- for (const param of data) {
130
- // Encode the parameter, and add it to the buffer.
131
- buffer.push(encode_script_data(param))
132
- }
133
- // Return the buffer as a single payload.
134
- return Buff.join(buffer)
135
- }
136
-
137
- export function encode_tx_locktime (locktime : number) : Buff {
138
- // Encode the locktime as a 4-byte little-endian number.
139
- return Buff.num(locktime, 4).reverse()
140
- }
141
-
142
- export function encode_script_data (
143
- script : string | null
144
- ) : Buff {
145
- // If the script is not null,
146
- if (script !== null) {
147
- // Assert that the script is a hex string.
148
- Assert.is_hex(script)
149
- // Encode the script, and add it to the buffer.
150
- return Buff.hex(script).prefix_varint('le')
151
- } else {
152
- // Return a single byte of zero.
153
- return Buff.hex('00')
154
- }
155
- }
@@ -1,7 +0,0 @@
1
- export * from './create.js'
2
- export * from './decode.js'
3
- export * from './encode.js'
4
- export * from './util.js'
5
- export * from './parse.js'
6
- export * from './size.js'
7
- export * from './validate.js'
@@ -1,69 +0,0 @@
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'
5
-
6
- import type { TxData, TxOutputTemplate } from '@/types/index.js'
7
-
8
- export function parse_tx (
9
- txdata : unknown,
10
- prevouts? : TxOutputTemplate[]
11
- ) : TxData {
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)
18
- } else {
19
- // Assert the txdata is a valid tx template.
20
- assert_tx_template(txdata)
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
- }
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 }
69
- }
@@ -1,68 +0,0 @@
1
- import { Buff, Bytes } from '@vbyte/buff'
2
- import { parse_tx } from './parse.js'
3
-
4
- import {
5
- encode_tx,
6
- encode_tx_inputs,
7
- encode_tx_outputs,
8
- encode_tx_vout,
9
- encode_vin,
10
- encode_vin_witness
11
- } from './encode.js'
12
-
13
- import type {
14
- TxData,
15
- TxInput,
16
- TxOutput,
17
- TxSize
18
- } from '@/types/index.js'
19
-
20
- const WIT_FLAG_BYTES = 2
21
-
22
- export function get_vsize (
23
- bytes : Bytes
24
- ) : number {
25
- const weight = Buff.bytes(bytes).length
26
- const remain = (weight % 4 > 0) ? 1 : 0
27
- return Math.ceil(weight / 4) + remain
28
- }
29
-
30
- export function get_txsize (
31
- txdata : string | TxData
32
- ) : TxSize {
33
- const json = parse_tx(txdata)
34
- const base = encode_tx(json, false).length
35
- const total = encode_tx(json, true).length
36
- const weight = base * 3 + total
37
- const remain = (weight % 4 > 0) ? 1 : 0
38
- const vsize = Math.ceil(weight / 4) + remain
39
- return { base, total, vsize, weight }
40
- }
41
-
42
- export function get_vin_size (vin : TxInput[]) : number {
43
- const bytes = encode_tx_inputs(vin)
44
- return bytes.length
45
- }
46
-
47
- export function get_vout_size (vout : TxOutput[]) : number {
48
- const bytes = encode_tx_outputs(vout)
49
- return bytes.length
50
- }
51
-
52
- export function get_segwit_size (txinputs : TxInput[]) : number {
53
- const segwit_data = txinputs
54
- .filter(e => e.witness.length > 0)
55
- .map(e => e.witness)
56
- return WIT_FLAG_BYTES + segwit_data
57
- .reduce((acc, e) => acc + encode_vin_witness(e).length, 0)
58
- }
59
-
60
- export function get_txin_size (txinput : TxInput) : number {
61
- const bytes = encode_vin(txinput)
62
- return bytes.length
63
- }
64
-
65
- export function get_txout_size (txoutput : TxOutput) : number {
66
- const bytes = encode_tx_vout(txoutput)
67
- return bytes.length
68
- }
@@ -1,111 +0,0 @@
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 { decode_tx } from './decode.js'
6
- import { encode_tx } from './encode.js'
7
- import { parse_tx } from './parse.js'
8
- import { assert_tx_template } from './validate.js'
9
-
10
- import { DEFAULT } from '@/const.js'
11
-
12
- import type {
13
- TxData,
14
- TxOutput,
15
- TxOutputTemplate,
16
- TxValue
17
- } from '@/types/index.js'
18
-
19
- export function transcode_tx (
20
- txdata : string | Uint8Array,
21
- use_segwit = true
22
- ) : Buff {
23
- // Decode the transaction data.
24
- const decoded = decode_tx(txdata)
25
- // Re-encode and return the encoded transaction data.
26
- return encode_tx(decoded, use_segwit)
27
- }
28
-
29
- export function get_txid (txdata : string | Uint8Array | TxData) : string {
30
- let buffer : Uint8Array
31
-
32
- if (txdata instanceof Uint8Array) {
33
- // Set the buffer to the transaction data.
34
- buffer = transcode_tx(txdata, false)
35
- } else if (typeof txdata === 'object') {
36
- // Assert the structure of the transaction data is valid.
37
- assert_tx_template(txdata)
38
- // Encode the transaction data.
39
- buffer = encode_tx(txdata, false)
40
- } else if (typeof txdata === 'string') {
41
- // Assert the transaction data is a hex string.
42
- Assert.is_hex(txdata)
43
- // Convert the hex string to a Uint8Array.
44
- buffer = transcode_tx(txdata, false)
45
- } else {
46
- throw new TypeError('invalid txdata type: ' + typeof txdata)
47
- }
48
- // Return the txid of the transaction data.
49
- return hash256(buffer).reverse().hex
50
- }
51
-
52
- export function get_txhash (txdata : string | Uint8Array | TxData) : string {
53
- // If the transaction data is an object,
54
- if (typeof txdata === 'object') {
55
- // Assert the structure of the transaction data is valid.
56
- assert_tx_template(txdata)
57
- // Encode the transaction data.
58
- txdata = encode_tx(txdata, true)
59
- }
60
- // Return the txhash of the transaction data.
61
- return hash256(txdata).reverse().hex
62
- }
63
-
64
- export function get_tx_value (txdata : string | Uint8Array | TxData) : TxValue {
65
- // Parse the transaction data.
66
- const tx = parse_tx(txdata)
67
- // Assert the structure of the transaction data is valid.
68
- assert_tx_template(tx)
69
- // Calculate the value of the transaction.
70
- const vin = tx.vin.reduce((acc, txin) => acc + (txin.prevout?.value ?? 0n), 0n)
71
- const vout = tx.vout.reduce((acc, txout) => acc + txout.value, 0n)
72
- const fees = (vin > vout) ? (vin - vout) : 0n
73
- // Return the value of the transaction.
74
- return { fees, vin, vout }
75
- }
76
-
77
- export function get_prevouts (txdata : TxData) : TxOutput[] {
78
- // Assert the structure of the transaction data is valid.
79
- assert_tx_template(txdata)
80
- // Collect the prevouts from the transaction.
81
- const prevouts = txdata.vin.map(e => e.prevout)
82
- // Assert that all the prevouts are defined.
83
- Assert.ok(prevouts.every(e => e !== null), 'prevouts missing from tx')
84
- // Return the array of prevouts.
85
- return prevouts
86
- }
87
-
88
- export function normalize_sequence (sequence? : number | string | null) : number {
89
- // If sequence is not defined, return a default sequence value.
90
- if (!Test.exists(sequence)) return DEFAULT.SEQUENCE
91
- // If sequence is a hex string, decode it and return the number value.
92
- if (Test.is_hex(sequence)) return Buff.hex(sequence as string, 4).reverse().num
93
- // If sequence is a valid unsigned integer, return the value.
94
- if (Test.is_uint(sequence)) return sequence
95
- // Else, throw an error.
96
- throw new Error('invalid sequence value: ' + String(sequence))
97
- }
98
-
99
- export function normalize_value (value : number | bigint) : bigint {
100
- // If value is a unsigned integer, return it as a bigint.
101
- if (Test.is_uint(value)) return BigInt(value)
102
- // If value is a bigint, return it as-is.
103
- if (typeof value === 'bigint') return value
104
- // Else, throw an error.
105
- throw new TypeError('invalid output value: ' + String(value))
106
- }
107
-
108
- export function normalize_prevout (prevout : TxOutputTemplate) : TxOutput {
109
- // Return the output with a normalized value.
110
- return { script_pk: prevout.script_pk, value: normalize_value(prevout.value) }
111
- }
@@ -1,49 +0,0 @@
1
- import * as Schema from '@/schema/index.js'
2
-
3
- import {
4
- TxSpendInput,
5
- TxData,
6
- TxInput,
7
- TxInputTemplate,
8
- TxOutput,
9
- TxTemplate,
10
- TxOutputTemplate,
11
- TxSpendData,
12
- } from '@/types/index.js'
13
-
14
- export function assert_tx_template (txdata : unknown) : asserts txdata is TxTemplate {
15
- Schema.tx.tx_template.parse(txdata)
16
- }
17
-
18
- export function assert_has_prevouts (vin : TxInput[]) : asserts vin is TxSpendInput[] {
19
- if (vin.some(txin => txin.prevout === null)) {
20
- throw new Error('transaction missing prevouts')
21
- }
22
- }
23
-
24
- export function assert_tx_data (txdata : unknown) : asserts txdata is TxData {
25
- Schema.tx.tx_data.parse(txdata)
26
- }
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
-
35
- export function assert_tx_input (tx_input : unknown) : asserts tx_input is TxInput {
36
- Schema.tx.tx_input.parse(tx_input)
37
- }
38
-
39
- export function assert_tx_output (tx_output : unknown) : asserts tx_output is TxOutput {
40
- Schema.tx.tx_output.parse(tx_output)
41
- }
42
-
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)
49
- }
@@ -1,2 +0,0 @@
1
- export * from './parse.js'
2
- export * from './util.js'
@@ -1,127 +0,0 @@
1
- import { Buff, Bytes } from '@vbyte/buff'
2
- import { is_valid_script } from '@/lib/script/decode.js'
3
- import { TAPLEAF_VERSIONS } from '@/const.js'
4
-
5
- import type {
6
- WitnessData,
7
- SpendScriptType,
8
- WitnessVersion
9
- } from '@/types/index.js'
10
-
11
- export function parse_witness (
12
- witness : Bytes[]
13
- ) : WitnessData {
14
- // Parse the witness data.
15
- const elems = witness.map(e => Buff.bytes(e))
16
- const stack = witness.map(e => Buff.bytes(e).hex)
17
- const annex = parse_annex_data(elems)
18
- if (annex !== null) elems.pop()
19
- const cblock = parse_cblock_data(elems)
20
- if (cblock !== null) elems.pop()
21
- const type = parse_witness_type(elems, cblock)
22
- const version = parse_witness_version(type)
23
- const script = parse_witness_script(elems, type)
24
- if (script !== null) elems.pop()
25
- const params = elems.map(e => e.hex)
26
- return { annex, cblock, params, script, stack, type, version }
27
- }
28
-
29
- function parse_annex_data (
30
- data : Uint8Array[]
31
- ) : string | null {
32
- // Get the last element of the array.
33
- let elem = data.at(-1)
34
- // Check if the element fits the annex format.
35
- if (
36
- data.length > 1 &&
37
- elem instanceof Uint8Array &&
38
- elem[0] === 0x50
39
- ) {
40
- // Return the element.
41
- return new Buff(elem).hex
42
- } else {
43
- // Return null.
44
- return null
45
- }
46
- }
47
-
48
- function parse_cblock_data (
49
- data : Uint8Array[]
50
- ) : string | null {
51
- let elem = data.at(-1)
52
- if (
53
- data.length > 1 &&
54
- elem instanceof Uint8Array &&
55
- elem.length > 32 &&
56
- TAPLEAF_VERSIONS.includes(elem[0] & 0xfe)
57
- ) {
58
- // Return the element.
59
- return new Buff(elem).hex
60
- } else {
61
- // Return null.
62
- return null
63
- }
64
- }
65
-
66
- function parse_witness_script (
67
- elems : Uint8Array[],
68
- type : SpendScriptType | null
69
- ) {
70
- let script : Uint8Array | undefined
71
- switch (type) {
72
- case 'p2ts':
73
- script = elems.at(-1)
74
- case 'p2wsh':
75
- script = elems.at(-1)
76
- }
77
- return (script !== undefined) ? new Buff(script).hex : null
78
- }
79
-
80
- function parse_witness_type (
81
- elems : Uint8Array[],
82
- cblock : string | null
83
- ) : SpendScriptType | null{
84
- // Get the important elements of the witness.
85
- let param_0 = elems.at(0),
86
- param_1 = elems.at(1),
87
- param_x = elems.at(-1)
88
- // If the cblock is present and the last element exists:
89
- if (cblock !== null && param_x !== undefined) {
90
- return 'p2ts'
91
- // If the witness elements match the profile of a p2w-pkh:
92
- } else if (
93
- elems.length === 2 &&
94
- param_0 !== undefined &&
95
- param_1 !== undefined &&
96
- param_0.length >= 64 &&
97
- param_1.length === 33
98
- ) {
99
- return 'p2wpkh'
100
- // If the witness elements match the profile of a p2tr-pk:
101
- } else if (
102
- elems.length === 1 &&
103
- param_0 !== undefined &&
104
- param_0.length === 64
105
- ) {
106
- return 'p2tr'
107
- // If there is at least two witness elements:
108
- } else if (
109
- elems.length > 1 &&
110
- param_x !== undefined &&
111
- is_valid_script(param_x)
112
- ) {
113
- return 'p2wsh'
114
- // If the witness elements don't match any known profile:
115
- } else {
116
- return null
117
- }
118
- }
119
-
120
- function parse_witness_version (
121
- type : SpendScriptType | null
122
- ) : WitnessVersion | null {
123
- if (type === null) return null
124
- if (type.startsWith('p2w')) return 0
125
- if (type.startsWith('p2t')) return 1
126
- return null
127
- }
@@ -1,18 +0,0 @@
1
- import { Buff, Bytes } from '@vbyte/buff'
2
- import { Assert } from '@vbyte/micro-lib'
3
-
4
- import type { WitnessSize } from '@/types/index.js'
5
-
6
- const WIT_LENGTH_BYTE = 1
7
-
8
- export function get_witness_size (witness : Bytes[]) : WitnessSize {
9
- const stack = witness.map(e => Buff.bytes(e))
10
- const size = stack.reduce((prev, next) => prev + next.length, 0)
11
- const vsize = Math.ceil(WIT_LENGTH_BYTE + size / 4)
12
- return { total: size, vsize }
13
- }
14
-
15
- export function assert_witness (witness : unknown) : asserts witness is Bytes[] {
16
- Assert.ok(Array.isArray(witness), 'witness must be an array')
17
- Assert.ok(witness.every(e => Buff.is_bytes(e)), 'witness must be an array of strings or bytes')
18
- }
@@ -1,57 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- type Literal = z.infer<typeof literal>
4
- type Json = Literal | { [key : string] : Json } | Json[]
5
-
6
- export const big = z.bigint()
7
- export const bool = z.boolean()
8
- export const date = z.date()
9
- export const num = z.number().min(Number.MIN_SAFE_INTEGER).max(Number.MAX_SAFE_INTEGER)
10
- export const int = num.int()
11
- export const u8a = z.instanceof(Uint8Array)
12
- export const str = z.string()
13
- export const stamp = int.min(500_000_000)
14
- export const any = z.any()
15
- export const zod = z
16
- export const char = int.min(0).max(0xFF)
17
- export const short = int.min(0).max(0xFFFF)
18
- export const uint = int.min(0).max(0xFFFFFFFF)
19
-
20
- export const float = z.number().refine((e) => String(e).includes('.'))
21
-
22
- export const float2 = float.refine((e) => {
23
- const parts = String(e).split('.').at(1)
24
- return parts !== undefined && parts.length <= 2
25
- })
26
-
27
- export const hex = z.string()
28
- .regex(/^[0-9a-fA-F]*$/)
29
- .refine(e => e.length % 2 === 0)
30
-
31
- export const literal = z.union([
32
- z.string(), z.number(), z.boolean(), z.null()
33
- ])
34
-
35
- export const json : z.ZodType<Json> = z.lazy(() =>
36
- z.union([ literal, z.array(json), z.record(str, json) ])
37
- )
38
-
39
- export const u8a20 = u8a.refine((e) => e.length === 20)
40
- export const u8a32 = u8a.refine((e) => e.length === 32)
41
- export const u8a33 = u8a.refine((e) => e.length === 33)
42
- export const u8a64 = u8a.refine((e) => e.length === 64)
43
-
44
- export const hex20 = hex.refine((e) => e.length === 40)
45
- export const hex32 = hex.refine((e) => e.length === 64)
46
- export const hex33 = hex.refine((e) => e.length === 66)
47
- export const hex64 = hex.refine((e) => e.length === 128)
48
-
49
- export const bytes = z.union([ hex, u8a ])
50
- export const byte32 = z.union([ hex32, u8a32 ])
51
- export const byte33 = z.union([ hex33, u8a33 ])
52
- export const byte64 = z.union([ hex64, u8a64 ])
53
-
54
- export const base58 = z.string().regex(/^[1-9A-HJ-NP-Za-km-z]+$/)
55
- export const base64 = z.string().regex(/^[a-zA-Z0-9+/]+={0,2}$/)
56
- export const base64url = z.string().regex(/^[a-zA-Z0-9\-_]+={0,2}$/)
57
- export const bech32 = z.string().regex(/^[a-z]+1[023456789acdefghjklmnpqrstuvwxyz]+$/)
@@ -1,2 +0,0 @@
1
- export * as taproot from './taproot.js'
2
- export * as tx from './tx.js'
@@ -1,12 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- import { byte32, uint } from './base.js'
4
-
5
- export const taptree = z.union([ z.array(byte32), byte32 ])
6
-
7
- export const config = z.object({
8
- pubkey : byte32,
9
- leaves : taptree.array().optional(),
10
- target : byte32.optional(),
11
- version : uint.optional(),
12
- })