@vbyte/btc-dev 1.0.10 → 1.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vbyte/btc-dev",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Batteries-included toolset for plebian bitcoin development",
5
5
  "type": "module",
6
6
  "keywords": [
package/src/class/tx.ts CHANGED
@@ -20,8 +20,6 @@ import type {
20
20
  TxData,
21
21
  TxTemplate,
22
22
  TxOutput,
23
- TxSize,
24
- TxValue,
25
23
  TxInputTemplate
26
24
  } from '@/types/index.js'
27
25
 
@@ -29,22 +27,8 @@ export class Transaction {
29
27
 
30
28
  private readonly _tx : TxData
31
29
 
32
- private _size : TxSize & { segwit : number }
33
- private _hash : string
34
- private _txid : string
35
- private _value : TxValue
36
- private _vin : TransactionInput[]
37
- private _vout : TransactionOutput[]
38
-
39
30
  constructor (txdata : string | TxData | TxTemplate = {}) {
40
- this._tx = parse_tx(txdata)
41
- this._vin = this._tx.vin.map(txin => new TransactionInput(txin))
42
- this._vout = this._tx.vout.map(txout => new TransactionOutput(txout))
43
-
44
- this._size = this._get_size()
45
- this._hash = get_txhash(this._tx)
46
- this._txid = get_txid(this._tx)
47
- this._value = get_tx_value(this._tx)
31
+ this._tx = parse_tx(txdata)
48
32
  }
49
33
 
50
34
  get data () : TxData {
@@ -52,7 +36,7 @@ export class Transaction {
52
36
  }
53
37
 
54
38
  get hash () : string {
55
- return this._hash
39
+ return get_txhash(this._tx)
56
40
  }
57
41
 
58
42
  get locktime () {
@@ -68,21 +52,21 @@ export class Transaction {
68
52
  }
69
53
 
70
54
  get size () {
71
- return this._size
55
+ return get_txsize(this._tx)
72
56
  }
73
57
 
74
- get spends () : TransactionOutput[] {
58
+ get spends () : TxOutput[] {
75
59
  return this._tx.vin
76
60
  .filter(txin => txin.prevout !== null)
77
- .map(txin => new TransactionOutput(txin.prevout!))
61
+ .map(txin => txin.prevout!)
78
62
  }
79
63
 
80
64
  get txid () : string {
81
- return this._txid
65
+ return get_txid(this._tx)
82
66
  }
83
67
 
84
68
  get value () {
85
- return this._value
69
+ return get_tx_value(this._tx)
86
70
  }
87
71
 
88
72
  get version () : number {
@@ -90,23 +74,21 @@ export class Transaction {
90
74
  }
91
75
 
92
76
  get vin () : TransactionInput[] {
93
- return this._vin
77
+ return this._tx.vin.map((_, idx) => new TransactionInput(this, idx))
94
78
  }
95
79
 
96
80
  get vout () : TransactionOutput[] {
97
- return this._vout
81
+ return this._tx.vout.map((_, idx) => new TransactionOutput(this, idx))
98
82
  }
99
83
 
100
84
  add_vin (tx_input : TxInputTemplate) {
101
85
  const txin = create_tx_input(tx_input)
102
86
  this._tx.vin.push(txin)
103
- this._update_vin()
104
87
  }
105
88
 
106
89
  add_vout (tx_output : TxOutput) {
107
90
  const txout = create_tx_output(tx_output)
108
91
  this._tx.vout.push(txout)
109
- this._update_vout()
110
92
  }
111
93
 
112
94
  insert_vin (index : number, tx_input : TxInputTemplate) {
@@ -117,7 +99,6 @@ export class Transaction {
117
99
  } else {
118
100
  this._tx.vin.splice(index, 0, txin)
119
101
  }
120
- this._update_vin()
121
102
  }
122
103
 
123
104
  insert_vout (index : number, tx_output : TxOutput) {
@@ -128,19 +109,16 @@ export class Transaction {
128
109
  } else {
129
110
  this._tx.vout.splice(index, 0, txout)
130
111
  }
131
- this._update_vout()
132
112
  }
133
113
 
134
114
  remove_vin (index : number) {
135
115
  Assert.ok(this._tx.vin.at(index) !== undefined, 'input does not exist at index')
136
116
  this._tx.vin.splice(index, 1)
137
- this._update_vin()
138
117
  }
139
118
 
140
119
  remove_vout (index : number) {
141
120
  Assert.ok(this._tx.vout.at(index) !== undefined, 'output does not exist at index')
142
121
  this._tx.vout.splice(index, 1)
143
- this._update_vout()
144
122
  }
145
123
 
146
124
  _get_size () {
@@ -153,23 +131,6 @@ export class Transaction {
153
131
  }
154
132
  }
155
133
 
156
- _update_tx () {
157
- this._size = this._get_size()
158
- this._hash = get_txhash(this._tx)
159
- this._txid = get_txid(this._tx)
160
- this._value = get_tx_value(this._tx)
161
- }
162
-
163
- _update_vin () {
164
- this._vin = this._tx.vin.map(txin => new TransactionInput(txin))
165
- this._update_tx()
166
- }
167
-
168
- _update_vout () {
169
- this._vout = this._tx.vout.map(txout => new TransactionOutput(txout))
170
- this._update_tx()
171
- }
172
-
173
134
  toJSON () { return this.data }
174
135
  toString () { return JSON.stringify(this.data) }
175
136
  }
package/src/class/txin.ts CHANGED
@@ -1,78 +1,86 @@
1
+ import { Assert } from '@vbyte/micro-lib'
2
+ import { Transaction } from './tx.js'
1
3
  import { decode_script } from '@/lib/script/index.js'
2
4
  import { SequenceUtil } from '@/lib/meta/index.js'
3
- import { TransactionOutput } from './txout.js'
4
5
  import { TransactionWitness } from './witness.js'
5
6
 
6
7
  import {
7
- assert_tx_input,
8
8
  encode_txin_sequence,
9
9
  get_txin_size,
10
10
  } from '@/lib/tx/index.js'
11
11
 
12
- import type { TxInput } from '@/types/index.js'
12
+ import type { TxInput, TxOutput } from '@/types/index.js'
13
13
 
14
14
  export class TransactionInput {
15
15
 
16
- private readonly _txin : TxInput
16
+ private readonly _tx : Transaction
17
+ private readonly _index : number
17
18
 
18
- constructor (txin : TxInput) {
19
- assert_tx_input(txin)
20
- this._txin = txin
19
+ constructor (
20
+ transaction : Transaction,
21
+ index : number
22
+ ) {
23
+ this._tx = transaction
24
+ this._index = index
21
25
  }
22
26
 
23
27
  get coinbase () : string | null {
24
- return this._txin.coinbase
28
+ return this.data.coinbase
25
29
  }
26
30
 
27
31
  get data () : TxInput {
28
- return this._txin
32
+ const txin = this._tx.data.vin.at(this.index)
33
+ Assert.exists(txin, 'txin not found')
34
+ return txin
29
35
  }
30
36
 
31
37
  get has_prevout () : boolean {
32
- return this._txin.prevout !== null
38
+ return this.data.prevout !== null
39
+ }
40
+
41
+ get index () : number {
42
+ return this._index
33
43
  }
34
44
 
35
45
  get is_coinbase () : boolean {
36
- return this._txin.coinbase !== null
46
+ return this.data.coinbase !== null
37
47
  }
38
48
 
39
- get prevout () : TransactionOutput | null {
40
- return this._txin.prevout
41
- ? new TransactionOutput(this._txin.prevout)
42
- : null
49
+ get prevout () : TxOutput | null {
50
+ return this.data.prevout
43
51
  }
44
52
 
45
53
  get script_sig () {
46
- if (this._txin.script_sig === null) return null
54
+ if (this.data.script_sig === null) return null
47
55
  return {
48
- asm : decode_script(this._txin.script_sig),
49
- hex : this._txin.script_sig
56
+ asm : decode_script(this.data.script_sig),
57
+ hex : this.data.script_sig
50
58
  }
51
59
  }
52
60
 
53
61
  get sequence () {
54
62
  return {
55
- hex : encode_txin_sequence(this._txin.sequence).hex,
56
- data : SequenceUtil.decode(this._txin.sequence),
57
- value : this._txin.sequence
63
+ hex : encode_txin_sequence(this.data.sequence).hex,
64
+ data : SequenceUtil.decode(this.data.sequence),
65
+ value : this.data.sequence
58
66
  }
59
67
  }
60
68
 
61
69
  get size () {
62
- return get_txin_size(this._txin)
70
+ return get_txin_size(this.data)
63
71
  }
64
72
 
65
73
  get txid () : string {
66
- return this._txin.txid
74
+ return this.data.txid
67
75
  }
68
76
 
69
77
  get vout () : number {
70
- return this._txin.vout
78
+ return this.data.vout
71
79
  }
72
80
 
73
81
  get witness () {
74
- return this._txin.witness.length > 0
75
- ? new TransactionWitness(this._txin.witness)
82
+ return this.data.witness.length > 0
83
+ ? new TransactionWitness(this._tx, this.index)
76
84
  : null
77
85
  }
78
86
 
@@ -1,7 +1,8 @@
1
+ import { Assert } from '@vbyte/micro-lib'
2
+ import { Transaction } from './tx.js'
1
3
  import { decode_script } from '@/lib/script/index.js'
2
4
 
3
5
  import {
4
- assert_tx_output,
5
6
  get_txout_size,
6
7
  get_vout_type,
7
8
  get_vout_version
@@ -11,38 +12,48 @@ import type { TxOutput } from '@/types/index.js'
11
12
 
12
13
  export class TransactionOutput {
13
14
 
14
- private readonly _txout : TxOutput
15
+ private readonly _tx : Transaction
16
+ private readonly _index : number
15
17
 
16
- constructor (txout : TxOutput) {
17
- assert_tx_output(txout)
18
- this._txout = txout
18
+ constructor (
19
+ transaction : Transaction,
20
+ index : number
21
+ ) {
22
+ this._tx = transaction
23
+ this._index = index
19
24
  }
20
25
 
21
26
  get data () : TxOutput {
22
- return this._txout
27
+ const txout = this._tx.data.vout.at(this.index)
28
+ Assert.exists(txout, 'txout not found')
29
+ return txout
30
+ }
31
+
32
+ get index () {
33
+ return this._index
23
34
  }
24
35
 
25
36
  get script_pk () {
26
37
  return {
27
- hex : this._txout.script_pk,
28
- asm : decode_script(this._txout.script_pk)
38
+ hex : this.data.script_pk,
39
+ asm : decode_script(this.data.script_pk)
29
40
  }
30
41
  }
31
42
 
32
43
  get size () {
33
- return get_txout_size(this._txout)
44
+ return get_txout_size(this.data)
34
45
  }
35
46
 
36
47
  get type () {
37
- return get_vout_type(this._txout.script_pk)
48
+ return get_vout_type(this.data.script_pk)
38
49
  }
39
50
 
40
51
  get value () : bigint {
41
- return this._txout.value
52
+ return this.data.value
42
53
  }
43
54
 
44
55
  get version () {
45
- return get_vout_version(this._txout.script_pk)
56
+ return get_vout_version(this.data.script_pk)
46
57
  }
47
58
 
48
59
  toJSON () { return this.data }
@@ -1,11 +1,10 @@
1
- import { Buff, Bytes } from '@vbyte/buff'
1
+ import { Transaction } from './tx.js'
2
2
  import { Assert } from '@vbyte/micro-lib'
3
3
  import { decode_script } from '@/lib/script/index.js'
4
4
 
5
5
  import {
6
6
  parse_witness,
7
- get_witness_size,
8
- assert_witness,
7
+ get_witness_size
9
8
  } from '@/lib/witness/index.js'
10
9
 
11
10
  import type {
@@ -17,81 +16,58 @@ import type {
17
16
 
18
17
  export class TransactionWitness {
19
18
 
20
- private readonly _elems : Buff[]
19
+ private readonly _tx : Transaction
20
+ private readonly _index : number
21
21
 
22
- private _data : WitnessData
23
- private _size : WitnessSize
24
-
25
- constructor (witness : Bytes[]) {
26
- assert_witness(witness)
27
- this._elems = witness.map(e => Buff.bytes(e))
28
- this._data = parse_witness(this._elems)
29
- this._size = get_witness_size(this._elems)
22
+ constructor (
23
+ transaction : Transaction,
24
+ index : number
25
+ ) {
26
+ this._tx = transaction
27
+ this._index = index
30
28
  }
31
29
 
32
30
  get annex () : string | null {
33
- return this._data.annex
31
+ return this.data.annex
34
32
  }
35
33
 
36
34
  get cblock () : string | null {
37
- return this._data.cblock
35
+ return this.data.cblock
38
36
  }
39
37
 
40
38
  get data () : WitnessData {
41
- return this._data
39
+ return parse_witness(this.stack)
42
40
  }
43
41
 
44
42
  get params () : string[] {
45
- return this._data.params
43
+ return this.data.params
46
44
  }
47
45
 
48
46
  get script () : ScriptField | null {
49
- if (this._data.script === null) return null
47
+ if (this.data.script === null) return null
50
48
  return {
51
- hex : this._data.script,
52
- asm : decode_script(this._data.script)
49
+ hex : this.data.script,
50
+ asm : decode_script(this.data.script)
53
51
  }
54
52
  }
55
53
 
56
54
  get size () : WitnessSize {
57
- return this._size
55
+ return get_witness_size(this.stack)
58
56
  }
59
57
 
60
58
  get stack () : string[] {
61
- return this._elems.map(e => e.hex)
59
+ const txin = this._tx.data.vin.at(this._index)
60
+ Assert.exists(txin, 'txin not found at index ' + this._index)
61
+ Assert.exists(txin.witness, 'witness not found at index ' + this._index)
62
+ return txin.witness
62
63
  }
63
64
 
64
65
  get type () : WitnessType {
65
- return this._data.type
66
+ return this.data.type
66
67
  }
67
68
 
68
69
  get version () : number | null {
69
- return this._data.version
70
- }
71
-
72
- _update () {
73
- this._data = parse_witness(this._elems)
74
- this._size = get_witness_size(this._elems)
75
- }
76
-
77
- add (elem : Bytes) {
78
- this._elems.push(Buff.bytes(elem))
79
- this._update()
80
- }
81
-
82
- insert (index : number, elem : Bytes) {
83
- Assert.ok(index >= 0 && index <= this._elems.length, 'index out of bounds')
84
- if (index === this._elems.length) {
85
- this._elems.push(Buff.bytes(elem))
86
- } else {
87
- this._elems.splice(index, 0, Buff.bytes(elem))
88
- }
89
- this._update()
90
- }
91
-
92
- remove (index : number) {
93
- this._elems.splice(index, 1)
94
- this._update()
70
+ return this.data.version
95
71
  }
96
72
 
97
73
  toJSON () { return this.data }