@vbyte/btc-dev 1.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 (205) hide show
  1. package/LICENSE +121 -0
  2. package/README.md +5 -0
  3. package/dist/class/index.d.ts +5 -0
  4. package/dist/class/index.js +5 -0
  5. package/dist/class/signer.d.ts +18 -0
  6. package/dist/class/signer.js +32 -0
  7. package/dist/class/tx.d.ts +38 -0
  8. package/dist/class/tx.js +73 -0
  9. package/dist/class/txin.d.ts +29 -0
  10. package/dist/class/txin.js +68 -0
  11. package/dist/class/txout.d.ts +18 -0
  12. package/dist/class/txout.js +38 -0
  13. package/dist/class/witness.d.ts +20 -0
  14. package/dist/class/witness.js +57 -0
  15. package/dist/const.d.ts +22 -0
  16. package/dist/const.js +36 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +10 -0
  19. package/dist/lib/address/encode.d.ts +3 -0
  20. package/dist/lib/address/encode.js +79 -0
  21. package/dist/lib/address/index.d.ts +20 -0
  22. package/dist/lib/address/index.js +21 -0
  23. package/dist/lib/address/p2pkh.d.ts +10 -0
  24. package/dist/lib/address/p2pkh.js +33 -0
  25. package/dist/lib/address/p2sh.d.ts +10 -0
  26. package/dist/lib/address/p2sh.js +33 -0
  27. package/dist/lib/address/p2tr.d.ts +8 -0
  28. package/dist/lib/address/p2tr.js +26 -0
  29. package/dist/lib/address/p2wpkh.d.ts +10 -0
  30. package/dist/lib/address/p2wpkh.js +34 -0
  31. package/dist/lib/address/p2wsh.d.ts +10 -0
  32. package/dist/lib/address/p2wsh.js +33 -0
  33. package/dist/lib/address/script.d.ts +5 -0
  34. package/dist/lib/address/script.js +46 -0
  35. package/dist/lib/address/util.d.ts +4 -0
  36. package/dist/lib/address/util.js +57 -0
  37. package/dist/lib/meta/index.d.ts +2 -0
  38. package/dist/lib/meta/index.js +2 -0
  39. package/dist/lib/meta/pointer.d.ts +42 -0
  40. package/dist/lib/meta/pointer.js +69 -0
  41. package/dist/lib/meta/scribe.d.ts +7 -0
  42. package/dist/lib/meta/scribe.js +192 -0
  43. package/dist/lib/psbt/encoder.d.ts +5 -0
  44. package/dist/lib/psbt/encoder.js +21 -0
  45. package/dist/lib/psbt/index.d.ts +4 -0
  46. package/dist/lib/psbt/index.js +4 -0
  47. package/dist/lib/psbt/meta.d.ts +3 -0
  48. package/dist/lib/psbt/meta.js +11 -0
  49. package/dist/lib/psbt/util.d.ts +5 -0
  50. package/dist/lib/psbt/util.js +44 -0
  51. package/dist/lib/psbt/validate.d.ts +2 -0
  52. package/dist/lib/psbt/validate.js +11 -0
  53. package/dist/lib/script/decode.d.ts +2 -0
  54. package/dist/lib/script/decode.js +55 -0
  55. package/dist/lib/script/encode.d.ts +6 -0
  56. package/dist/lib/script/encode.js +80 -0
  57. package/dist/lib/script/index.d.ts +126 -0
  58. package/dist/lib/script/index.js +17 -0
  59. package/dist/lib/script/util.d.ts +2 -0
  60. package/dist/lib/script/util.js +10 -0
  61. package/dist/lib/script/words.d.ts +116 -0
  62. package/dist/lib/script/words.js +164 -0
  63. package/dist/lib/sighash/index.d.ts +5 -0
  64. package/dist/lib/sighash/index.js +5 -0
  65. package/dist/lib/sighash/segwit.d.ts +3 -0
  66. package/dist/lib/sighash/segwit.js +89 -0
  67. package/dist/lib/sighash/sign.d.ts +3 -0
  68. package/dist/lib/sighash/sign.js +20 -0
  69. package/dist/lib/sighash/taproot.d.ts +9 -0
  70. package/dist/lib/sighash/taproot.js +124 -0
  71. package/dist/lib/sighash/util.d.ts +3 -0
  72. package/dist/lib/sighash/util.js +16 -0
  73. package/dist/lib/sighash/verify.d.ts +1 -0
  74. package/dist/lib/sighash/verify.js +1 -0
  75. package/dist/lib/taproot/cblock.d.ts +3 -0
  76. package/dist/lib/taproot/cblock.js +55 -0
  77. package/dist/lib/taproot/encode.d.ts +6 -0
  78. package/dist/lib/taproot/encode.js +26 -0
  79. package/dist/lib/taproot/index.d.ts +4 -0
  80. package/dist/lib/taproot/index.js +4 -0
  81. package/dist/lib/taproot/parse.d.ts +11 -0
  82. package/dist/lib/taproot/parse.js +47 -0
  83. package/dist/lib/taproot/tree.d.ts +3 -0
  84. package/dist/lib/taproot/tree.js +49 -0
  85. package/dist/lib/tx/create.d.ts +6 -0
  86. package/dist/lib/tx/create.js +54 -0
  87. package/dist/lib/tx/decode.d.ts +9 -0
  88. package/dist/lib/tx/decode.js +109 -0
  89. package/dist/lib/tx/encode.d.ts +15 -0
  90. package/dist/lib/tx/encode.js +94 -0
  91. package/dist/lib/tx/index.d.ts +10 -0
  92. package/dist/lib/tx/index.js +10 -0
  93. package/dist/lib/tx/locktime.d.ts +7 -0
  94. package/dist/lib/tx/locktime.js +37 -0
  95. package/dist/lib/tx/meta.d.ts +8 -0
  96. package/dist/lib/tx/meta.js +48 -0
  97. package/dist/lib/tx/parse.d.ts +2 -0
  98. package/dist/lib/tx/parse.js +12 -0
  99. package/dist/lib/tx/sequence.d.ts +7 -0
  100. package/dist/lib/tx/sequence.js +65 -0
  101. package/dist/lib/tx/size.d.ts +10 -0
  102. package/dist/lib/tx/size.js +48 -0
  103. package/dist/lib/tx/validate.d.ts +7 -0
  104. package/dist/lib/tx/validate.js +21 -0
  105. package/dist/lib/tx/witness.d.ts +3 -0
  106. package/dist/lib/tx/witness.js +85 -0
  107. package/dist/main.cjs +14625 -0
  108. package/dist/main.cjs.map +1 -0
  109. package/dist/module.mjs +14610 -0
  110. package/dist/module.mjs.map +1 -0
  111. package/dist/package.json +106 -0
  112. package/dist/schema/index.d.ts +2 -0
  113. package/dist/schema/index.js +2 -0
  114. package/dist/schema/taproot.d.ts +18 -0
  115. package/dist/schema/taproot.js +9 -0
  116. package/dist/schema/tx.d.ts +278 -0
  117. package/dist/schema/tx.js +35 -0
  118. package/dist/script.js +15 -0
  119. package/dist/script.js.map +1 -0
  120. package/dist/types/address.d.ts +34 -0
  121. package/dist/types/address.js +1 -0
  122. package/dist/types/index.d.ts +9 -0
  123. package/dist/types/index.js +9 -0
  124. package/dist/types/meta.d.ts +10 -0
  125. package/dist/types/meta.js +1 -0
  126. package/dist/types/psbt.d.ts +9 -0
  127. package/dist/types/psbt.js +1 -0
  128. package/dist/types/sighash.d.ts +14 -0
  129. package/dist/types/sighash.js +1 -0
  130. package/dist/types/taproot.d.ts +35 -0
  131. package/dist/types/taproot.js +1 -0
  132. package/dist/types/transaction.d.ts +81 -0
  133. package/dist/types/transaction.js +1 -0
  134. package/dist/types/txdata.d.ts +45 -0
  135. package/dist/types/txdata.js +1 -0
  136. package/dist/types/txmeta.d.ts +19 -0
  137. package/dist/types/txmeta.js +1 -0
  138. package/dist/types/witness.d.ts +30 -0
  139. package/dist/types/witness.js +1 -0
  140. package/package.json +106 -0
  141. package/src/class/index.ts +5 -0
  142. package/src/class/signer.ts +47 -0
  143. package/src/class/tx.ts +118 -0
  144. package/src/class/txin.ts +95 -0
  145. package/src/class/txout.ts +57 -0
  146. package/src/class/witness.ts +85 -0
  147. package/src/const.ts +43 -0
  148. package/src/index.ts +14 -0
  149. package/src/lib/address/encode.ts +183 -0
  150. package/src/lib/address/index.ts +24 -0
  151. package/src/lib/address/p2pkh.ts +65 -0
  152. package/src/lib/address/p2sh.ts +65 -0
  153. package/src/lib/address/p2tr.ts +51 -0
  154. package/src/lib/address/p2wpkh.ts +67 -0
  155. package/src/lib/address/p2wsh.ts +65 -0
  156. package/src/lib/address/script.ts +63 -0
  157. package/src/lib/address/util.ts +102 -0
  158. package/src/lib/meta/index.ts +2 -0
  159. package/src/lib/meta/pointer.ts +107 -0
  160. package/src/lib/meta/scribe.ts +251 -0
  161. package/src/lib/psbt/encoder.ts +24 -0
  162. package/src/lib/psbt/index.ts +4 -0
  163. package/src/lib/psbt/meta.ts +15 -0
  164. package/src/lib/psbt/util.ts +62 -0
  165. package/src/lib/psbt/validate.ts +18 -0
  166. package/src/lib/script/decode.ts +75 -0
  167. package/src/lib/script/encode.ts +130 -0
  168. package/src/lib/script/index.ts +26 -0
  169. package/src/lib/script/util.ts +78 -0
  170. package/src/lib/script/words.ts +182 -0
  171. package/src/lib/sighash/index.ts +5 -0
  172. package/src/lib/sighash/segwit.ts +152 -0
  173. package/src/lib/sighash/sign.ts +35 -0
  174. package/src/lib/sighash/taproot.ts +236 -0
  175. package/src/lib/sighash/util.ts +29 -0
  176. package/src/lib/sighash/verify.ts +83 -0
  177. package/src/lib/taproot/cblock.ts +95 -0
  178. package/src/lib/taproot/encode.ts +49 -0
  179. package/src/lib/taproot/index.ts +4 -0
  180. package/src/lib/taproot/parse.ts +65 -0
  181. package/src/lib/taproot/tree.ts +94 -0
  182. package/src/lib/tx/create.ts +82 -0
  183. package/src/lib/tx/decode.ts +145 -0
  184. package/src/lib/tx/encode.ts +154 -0
  185. package/src/lib/tx/index.ts +10 -0
  186. package/src/lib/tx/locktime.ts +57 -0
  187. package/src/lib/tx/meta.ts +73 -0
  188. package/src/lib/tx/parse.ts +16 -0
  189. package/src/lib/tx/sequence.ts +146 -0
  190. package/src/lib/tx/size.ts +77 -0
  191. package/src/lib/tx/validate.ts +36 -0
  192. package/src/lib/tx/witness.ts +122 -0
  193. package/src/schema/index.ts +2 -0
  194. package/src/schema/taproot.ts +12 -0
  195. package/src/schema/tx.ts +42 -0
  196. package/src/types/address.ts +39 -0
  197. package/src/types/index.ts +9 -0
  198. package/src/types/meta.ts +10 -0
  199. package/src/types/psbt.ts +15 -0
  200. package/src/types/sighash.ts +16 -0
  201. package/src/types/taproot.ts +40 -0
  202. package/src/types/transaction.ts +98 -0
  203. package/src/types/txdata.ts +53 -0
  204. package/src/types/txmeta.ts +25 -0
  205. package/src/types/witness.ts +36 -0
@@ -0,0 +1,95 @@
1
+ import { decode_script } from '@/lib/script/index.js'
2
+ import { TransactionOutput } from './txout.js'
3
+ import { TransactionWitness } from './witness.js'
4
+
5
+ import {
6
+ encode_txin_sequence,
7
+ get_txin_size,
8
+ Sequence
9
+ } from '@/lib/tx/index.js'
10
+
11
+ import type {
12
+ TxInput,
13
+ TxInputField
14
+ } from '@/types/index.js'
15
+
16
+ export class TransactionInput {
17
+
18
+ private readonly _size : number
19
+ private readonly _txin : TxInput
20
+ private readonly _witness : TransactionWitness | null
21
+
22
+ constructor (txin : TxInput) {
23
+ this._size = get_txin_size(txin)
24
+ this._txin = txin
25
+ this._witness = txin.witness.length > 0
26
+ ? new TransactionWitness(txin.witness)
27
+ : null
28
+ }
29
+
30
+ get coinbase () : string | null {
31
+ return this._txin.coinbase
32
+ }
33
+
34
+ get data () : TxInputField {
35
+ return {
36
+ coinbase : this.coinbase,
37
+ prevout : this.prevout?.data ?? null,
38
+ script_sig : this.script_sig,
39
+ sequence : this.sequence,
40
+ size : this.size,
41
+ txid : this.txid,
42
+ vout : this.vout,
43
+ witness : this.witness?.data ?? null
44
+ }
45
+ }
46
+
47
+ get has_prevout () : boolean {
48
+ return this._txin.prevout !== null
49
+ }
50
+
51
+ get is_coinbase () : boolean {
52
+ return this._txin.coinbase !== null
53
+ }
54
+
55
+ get prevout () : TransactionOutput | null {
56
+ return this._txin.prevout
57
+ ? new TransactionOutput(this._txin.prevout)
58
+ : null
59
+ }
60
+
61
+ get script_sig () {
62
+ if (this._txin.script_sig === null) return null
63
+ return {
64
+ asm : decode_script(this._txin.script_sig),
65
+ hex : this._txin.script_sig
66
+ }
67
+ }
68
+
69
+ get sequence () {
70
+ return {
71
+ hex : encode_txin_sequence(this._txin.sequence).hex,
72
+ data : Sequence.decode(this._txin.sequence),
73
+ value : this._txin.sequence
74
+ }
75
+ }
76
+
77
+ get size () {
78
+ return this._size
79
+ }
80
+
81
+ get txid () : string {
82
+ return this._txin.txid
83
+ }
84
+
85
+ get vout () : number {
86
+ return this._txin.vout
87
+ }
88
+
89
+ get witness () {
90
+ return this._witness
91
+ }
92
+
93
+ toJSON () { return this.data }
94
+ toString () { return JSON.stringify(this.data) }
95
+ }
@@ -0,0 +1,57 @@
1
+ import { decode_script } from '@/lib/script/index.js'
2
+
3
+ import {
4
+ get_txout_size,
5
+ get_vout_info
6
+ } from '@/lib/tx/index.js'
7
+
8
+ import type { TxOutput, TxOutputField, TxOutputInfo } from '@/types/index.js'
9
+
10
+ export class TransactionOutput {
11
+
12
+ private readonly _info : TxOutputInfo
13
+ private readonly _size : number
14
+ private readonly _txout : TxOutput
15
+
16
+ constructor (txout : TxOutput) {
17
+ this._info = get_vout_info(txout)
18
+ this._size = get_txout_size(txout)
19
+ this._txout = txout
20
+ }
21
+
22
+ get data () : TxOutputField {
23
+ return {
24
+ script_pk : this.script_pk,
25
+ size : this.size,
26
+ type : this.type,
27
+ value : this.value,
28
+ version : this.version
29
+ }
30
+ }
31
+
32
+ get script_pk () {
33
+ return {
34
+ hex : this._txout.script_pk,
35
+ asm : decode_script(this._txout.script_pk)
36
+ }
37
+ }
38
+
39
+ get size () {
40
+ return this._size
41
+ }
42
+
43
+ get type () {
44
+ return this._info.type
45
+ }
46
+
47
+ get value () : bigint {
48
+ return this._txout.value
49
+ }
50
+
51
+ get version () {
52
+ return this._info.version
53
+ }
54
+
55
+ toJSON () { return this.data }
56
+ toString () { return JSON.stringify(this.data) }
57
+ }
@@ -0,0 +1,85 @@
1
+ import { Buff, Bytes } from '@vbyte/buff'
2
+ import { decode_script } from '@/lib/script/index.js'
3
+
4
+ import {
5
+ parse_witness_data,
6
+ get_witness_size,
7
+ } from '@/lib/tx/index.js'
8
+
9
+ import type {
10
+ ScriptField,
11
+ WitnessField,
12
+ WitnessInfo,
13
+ WitnessSize,
14
+ WitnessType
15
+ } from '@/types/index.js'
16
+
17
+ export class TransactionWitness {
18
+
19
+ private readonly _data : Buff[]
20
+ private readonly _meta : WitnessInfo
21
+ private readonly _size : WitnessSize
22
+
23
+ constructor (witness : Bytes[]) {
24
+ this._data = witness.map(e => Buff.bytes(e))
25
+ this._meta = parse_witness_data(witness)
26
+ this._size = get_witness_size(witness)
27
+ }
28
+
29
+ get annex () : string | null {
30
+ return this._meta.annex
31
+ }
32
+
33
+ get cblock () : string | null {
34
+ return this._meta.cblock
35
+ }
36
+
37
+ get data () : WitnessField {
38
+ return {
39
+ annex : this.annex,
40
+ cblock : this.cblock,
41
+ params : this.params,
42
+ script : this.script,
43
+ size : this.size,
44
+ stack : this.stack,
45
+ type : this.type,
46
+ version : this.version,
47
+ vsize : this.vsize
48
+ }
49
+ }
50
+
51
+ get params () : string[] {
52
+ return this._meta.params
53
+ }
54
+
55
+ get script () : ScriptField | null {
56
+ if (this._meta.script === null) return null
57
+ return {
58
+ hex : this._meta.script,
59
+ asm : decode_script(this._meta.script)
60
+ }
61
+ }
62
+
63
+ get size () : number {
64
+ return this._size.size
65
+ }
66
+
67
+ get stack () : string[] {
68
+ return this._data.map(e => e.hex)
69
+ }
70
+
71
+ get type () : WitnessType {
72
+ return this._meta.type
73
+ }
74
+
75
+ get version () : number | null {
76
+ return this._meta.version
77
+ }
78
+
79
+ get vsize () : number {
80
+ return this._size.vsize
81
+ }
82
+
83
+ toJSON () { return this.data }
84
+ toString () { return JSON.stringify(this.data) }
85
+ }
package/src/const.ts ADDED
@@ -0,0 +1,43 @@
1
+ export const COINBASE = {
2
+ TXID : '00'.repeat(32),
3
+ VOUT : 0xFFFFFFFF,
4
+ }
5
+
6
+ export const DEFAULT = {
7
+ LOCKTIME : 0,
8
+ SEQUENCE : 0xFFFFFFFF,
9
+ VERSION : 2,
10
+ }
11
+
12
+ export const TAPLEAF_VERSIONS = [
13
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,
14
+ 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
15
+ 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
16
+ 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
17
+ 0x66, 0x7e, 0x80, 0x84, 0x96, 0x98, 0xba, 0xbc,
18
+ 0xbe
19
+ ]
20
+
21
+ export const TAPLEAF_DEFAULT_VERSION = 0xc0
22
+
23
+ export const LOCK_SCRIPT_REGEX : Record<string, RegExp> = {
24
+ 'p2pkh' : /^76a914[0-9a-f]{40}88ac$/i,
25
+ 'p2sh' : /^a914[0-9a-f]{40}87$/i,
26
+ 'p2wpkh' : /^0014[0-9a-f]{40}$/i,
27
+ 'p2wsh' : /^0020[0-9a-f]{64}$/i,
28
+ 'p2tr' : /^5120[0-9a-f]{64}$/i,
29
+ 'opreturn' : /^6a[0-9a-f]{2,}$/i,
30
+ }
31
+
32
+ export const SCRIPT_INT_KEY = ''
33
+
34
+ export const TX_SIZE = {
35
+ GLOBAL_BASE : 8,
36
+ GLOBAL_WIT : 10,
37
+ TXIN_BASE : 32 + 4 + 4,
38
+ TXOUT_BASE : 8,
39
+ }
40
+
41
+ export const SIGHASH_DEFAULT = 0x01
42
+ export const SIGHASH_SEGWIT = [ 0x01, 0x02, 0x03, 0x81, 0x82, 0x83 ]
43
+ export const SIGHASH_TAPROOT = [ 0x00, ...SIGHASH_SEGWIT ]
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ export * from './class/index.js'
2
+
3
+ export * as Address from './lib/address/index.js'
4
+ export * as Meta from './lib/meta/index.js'
5
+ export * as PSBT from './lib/psbt/index.js'
6
+ export * as Script from './lib/script/index.js'
7
+ export * as Sighash from './lib/sighash/index.js'
8
+ export * as Taproot from './lib/taproot/index.js'
9
+ export * as Tx from './lib/tx/index.js'
10
+
11
+ export * as CONST from './const.js'
12
+ export * as SCHEMA from './schema/index.js'
13
+
14
+ export type * from './types/index.js'
@@ -0,0 +1,183 @@
1
+ import { Buff } from '@vbyte/buff'
2
+
3
+ import { Assert, B58chk, Bech32, Bech32m } from '@vbyte/micro-lib'
4
+
5
+ import type {
6
+ AddressFormat,
7
+ DecodedAddress,
8
+ } from '@/types/address.js'
9
+
10
+ const ENCODING_REGEX = {
11
+ base58 : /^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/,
12
+ bech32 : /^(bc|tb|bcrt)1q[ac-hj-np-z02-9]{6,87}$/,
13
+ bech32m : /^(bc|tb|bcrt)1p[ac-hj-np-z02-9]{6,87}$/
14
+ }
15
+
16
+ const VERSION = {
17
+ bech32 : 0,
18
+ bech32m : 1
19
+ }
20
+
21
+ /**
22
+ * Decode an address.
23
+ *
24
+ * @param address - The address to decode.
25
+ * @returns The decoded address.
26
+ */
27
+ export function decode_address (address : string) : DecodedAddress {
28
+ // Get the address format.
29
+ const format = get_address_format(address)
30
+ // If the format is not found, throw an error.
31
+ if (format === null) throw new Error('unrecognized address format: ' + format)
32
+ // Decode the address based on the format.
33
+ if (format === 'base58') return base58_decode(address)
34
+ if (format === 'bech32') return bech32_decode(address)
35
+ if (format === 'bech32m') return bech32m_decode(address)
36
+ // If we didn't find a matching decoder, throw.
37
+ throw new Error('unable to find a matching address configuration')
38
+ }
39
+
40
+ /**
41
+ * Encode an address.
42
+ *
43
+ * @param address - The address to encode.
44
+ * @returns The encoded address as a string, or null if the address is not
45
+ * recognized.
46
+ */
47
+ export function encode_address (
48
+ config : DecodedAddress
49
+ ) : string {
50
+ // Encode the address based on the format.
51
+ if (config.format === 'base58') return base58_encode(config)
52
+ if (config.format === 'bech32') return bech32_encode(config)
53
+ if (config.format === 'bech32m') return bech32m_encode(config)
54
+ // If the format is not recognized, throw an error.
55
+ throw new Error('unrecognized encoding format: ' + config.format)
56
+ }
57
+
58
+ /**
59
+ * Get the encoding type for a given address.
60
+ *
61
+ * @param address - The address to get the encoding type for.
62
+ * @returns The encoding type, or null if the address is not recognized.
63
+ */
64
+ function get_address_format (address : string) : AddressFormat | null {
65
+ // For each encoding type, check if the address matches the regex.
66
+ for (const [ format, regex ] of Object.entries(ENCODING_REGEX)) {
67
+ // If the address matches the regex, return the format.
68
+ if (regex.test(address)) return format as AddressFormat
69
+ // If the address does not match the regex, continue to the next encoding type.
70
+ }
71
+ // If no encoding type matches the address, return null.
72
+ return null
73
+ }
74
+
75
+ /**
76
+ * Encode data as a base58 string.
77
+ *
78
+ * @param config - The encoder configuration.
79
+ * @returns The encoded base58 string.
80
+ */
81
+ function base58_encode (config : DecodedAddress) : string {
82
+ // Assert the format is correct.
83
+ Assert.ok(config.format === 'base58', 'encoding mismatch')
84
+ // Assert the version is specified.
85
+ Assert.exists(config.version, 'must specify a version')
86
+ // Convert the data into bytes with a version prefix.
87
+ const bytes = Buff.join([ config.version, config.data ])
88
+ // Encode the data as a base58 string.
89
+ return B58chk.encode(bytes)
90
+ }
91
+
92
+ /**
93
+ * Decode data as a base58 string.
94
+ *
95
+ * @param encoded - The base58 string to decode.
96
+ * @returns The decoded data.
97
+ */
98
+ function base58_decode (encoded : string) : DecodedAddress {
99
+ // Decode the encoded data.
100
+ const bytes = B58chk.decode(encoded)
101
+ // Get the data from the decoded bytes.
102
+ const data = bytes.slice(1)
103
+ // Get the version from the decoded bytes.
104
+ const version = bytes[0]
105
+ // Return the decoded address.
106
+ return { data, format: 'base58', version }
107
+ }
108
+
109
+ /**
110
+ * Encode data as a bech32 string.
111
+ *
112
+ * @param config - The encoder configuration.
113
+ * @returns The encoded bech32 string.
114
+ */
115
+ function bech32_encode (config : DecodedAddress) : string {
116
+ // Assert the format is correct.
117
+ Assert.ok(config.format === 'bech32', 'encoding mismatch')
118
+ // Assert the prefix is specified.
119
+ Assert.exists(config.prefix, 'prefix is required')
120
+ // Convert the data into bytes.
121
+ const bytes = Buff.bytes(config.data)
122
+ // Convert the bytes into words.
123
+ const words = Bech32.to_words(bytes)
124
+ // Encode the data as a bech32 string.
125
+ return Bech32.encode(config.prefix, [ VERSION.bech32, ...words ])
126
+ }
127
+
128
+ /**
129
+ * Decode data as a bech32 string.
130
+ *
131
+ * @param encoded - The bech32 string to decode.
132
+ * @returns The decoded data.
133
+ */
134
+ function bech32_decode (encoded : string) : DecodedAddress {
135
+ // Decode the encoded data.
136
+ const { prefix, words } = Bech32.decode(encoded)
137
+ // Get the version and rest of the words.
138
+ const [ version, ...rest ] = words
139
+ // Assert the version is correct.
140
+ Assert.ok(version === VERSION.bech32, 'bech32 version mismatch')
141
+ // Convert the rest of the words into bytes.
142
+ const data = Bech32.to_bytes(rest)
143
+ // Return the decoded address.
144
+ return { data, format: 'bech32', prefix, version }
145
+ }
146
+
147
+ /**
148
+ * Encode data as a bech32 string.
149
+ *
150
+ * @param config - The encoder configuration.
151
+ * @returns The encoded bech32 string.
152
+ */
153
+ function bech32m_encode (config : DecodedAddress) : string {
154
+ // Assert the format is correct.
155
+ Assert.ok(config.format === 'bech32m', 'encoding mismatch')
156
+ // Assert the prefix is specified.
157
+ Assert.exists(config.prefix, 'prefix is required')
158
+ // Convert the data into bytes.
159
+ const bytes = Buff.bytes(config.data)
160
+ // Convert the bytes into words.
161
+ const words = Bech32m.to_words(bytes)
162
+ // Encode the data as a bech32m string.
163
+ return Bech32m.encode(config.prefix, [ VERSION.bech32m, ...words ])
164
+ }
165
+
166
+ /**
167
+ * Decode data as a bech32 string.
168
+ *
169
+ * @param encoded - The bech32 string to decode.
170
+ * @returns The decoded data.
171
+ */
172
+ function bech32m_decode (encoded : string) : DecodedAddress {
173
+ // Decode the encoded data.
174
+ const { prefix, words } = Bech32m.decode(encoded)
175
+ // Get the version and rest of the words.
176
+ const [ version, ...rest ] = words
177
+ // Assert the version is correct.
178
+ Assert.ok(version === VERSION.bech32m, 'bech32m version mismatch')
179
+ // Convert the rest of the words into bytes.
180
+ const data = Bech32m.to_bytes(rest)
181
+ // Return the decoded address.
182
+ return { data, format: 'bech32m', prefix, version }
183
+ }
@@ -0,0 +1,24 @@
1
+ import { P2PKH as P2PKH_TOOL } from './p2pkh.js'
2
+ import { P2SH as P2SH_TOOL } from './p2sh.js'
3
+ import { P2WPKH as P2WPKH_TOOL } from './p2wpkh.js'
4
+ import { P2WSH as P2WSH_TOOL } from './p2wsh.js'
5
+ import { P2TR as P2TR_TOOL } from './p2tr.js'
6
+
7
+ import { parse_address } from './util.js'
8
+
9
+ export { P2PKH } from './p2pkh.js'
10
+ export { P2SH } from './p2sh.js'
11
+ export { P2WPKH } from './p2wpkh.js'
12
+ export { P2WSH } from './p2wsh.js'
13
+ export { P2TR } from './p2tr.js'
14
+
15
+ export { parse_address } from './util.js'
16
+
17
+ export namespace AddressTool {
18
+ export const P2PKH = P2PKH_TOOL
19
+ export const P2SH = P2SH_TOOL
20
+ export const P2WPKH = P2WPKH_TOOL
21
+ export const P2WSH = P2WSH_TOOL
22
+ export const P2TR = P2TR_TOOL
23
+ export const parse = parse_address
24
+ }
@@ -0,0 +1,65 @@
1
+ import { Buff } from '@vbyte/buff'
2
+ import { Assert } from '@vbyte/micro-lib'
3
+ import { hash160 } from '@vbyte/micro-lib/hash'
4
+ import { encode_address } from './encode.js'
5
+
6
+ import {
7
+ get_address_config,
8
+ parse_address
9
+ } from './util.js'
10
+
11
+ import type {
12
+ AddressData,
13
+ ChainNetwork
14
+ } from '@/types/index.js'
15
+
16
+ const ADDR_TYPE = 'p2pkh'
17
+
18
+ export namespace P2PKH {
19
+ export const create = create_p2pkh_address
20
+ export const encode = encode_p2pkh_address
21
+ export const decode = decode_p2pkh_address
22
+ }
23
+
24
+ function create_p2pkh_address (
25
+ script : string | Uint8Array,
26
+ network : ChainNetwork = 'main',
27
+ ) : string {
28
+ // Convert the script into bytes.
29
+ const bytes = Buff.bytes(script)
30
+ // Convert the bytes into a hash.
31
+ const hash = hash160(bytes)
32
+ // Encode the hash as an address.
33
+ return encode_p2pkh_address(hash, network)
34
+ }
35
+
36
+ function encode_p2pkh_address (
37
+ pk_hash : string | Uint8Array,
38
+ network : ChainNetwork = 'main',
39
+ ) : string {
40
+ // Convert the public key hash into bytes.
41
+ const bytes = Buff.bytes(pk_hash)
42
+ // Get the address configuration.
43
+ const config = get_address_config(network, ADDR_TYPE)
44
+ // Assert the configuration exists.
45
+ Assert.exists(config, `unrecognized address config: ${ADDR_TYPE} on ${network}` )
46
+ // Assert the payload size is correct.
47
+ Assert.size(bytes, config.size, `invalid payload size: ${bytes.length} !== ${config.size}` )
48
+ // Encode the address.
49
+ return encode_address({
50
+ data : bytes,
51
+ format : 'base58',
52
+ version : config.version
53
+ })
54
+ }
55
+
56
+ function decode_p2pkh_address (
57
+ address : string
58
+ ) : AddressData {
59
+ // Parse the address.
60
+ const parsed = parse_address(address)
61
+ // Assert the address type is correct.
62
+ Assert.ok(parsed.type === 'p2pkh', `address type mismatch: ${parsed.type} !== ${ADDR_TYPE}`)
63
+ // Return the parsed address.
64
+ return parsed
65
+ }
@@ -0,0 +1,65 @@
1
+ import { Buff } from '@vbyte/buff'
2
+ import { Assert } from '@vbyte/micro-lib'
3
+ import { hash160 } from '@vbyte/micro-lib/hash'
4
+ import { encode_address } from './encode.js'
5
+
6
+ import {
7
+ get_address_config,
8
+ parse_address
9
+ } from './util.js'
10
+
11
+ import type {
12
+ ChainNetwork,
13
+ AddressData
14
+ } from '@/types/index.js'
15
+
16
+ const ADDR_TYPE = 'p2sh'
17
+
18
+ export namespace P2SH {
19
+ export const create = create_p2sh_address
20
+ export const encode = encode_p2sh_address
21
+ export const decode = decode_p2sh_address
22
+ }
23
+
24
+ function create_p2sh_address (
25
+ script : string | Uint8Array,
26
+ network : ChainNetwork = 'main',
27
+ ) : string {
28
+ // Convert the script into bytes.
29
+ const bytes = Buff.bytes(script)
30
+ // Convert the bytes into a hash.
31
+ const hash = hash160(bytes)
32
+ // Encode the address.
33
+ return encode_p2sh_address(hash, network)
34
+ }
35
+
36
+ function encode_p2sh_address (
37
+ script_hash : string | Uint8Array,
38
+ network : ChainNetwork = 'main',
39
+ ) : string {
40
+ // Convert the script hash into bytes.
41
+ const bytes = Buff.bytes(script_hash)
42
+ // Get the address configuration.
43
+ const config = get_address_config(network, ADDR_TYPE)
44
+ // Assert the configuration exists.
45
+ Assert.exists(config, `unrecognized address config: ${ADDR_TYPE} on ${network}` )
46
+ // Assert the payload size is correct.
47
+ Assert.size(bytes, config.size, `invalid payload size: ${bytes.length} !== ${config.size}` )
48
+ // Encode the address.
49
+ return encode_address({
50
+ data : bytes,
51
+ format : 'base58',
52
+ version : config.version
53
+ })
54
+ }
55
+
56
+ function decode_p2sh_address (
57
+ address : string
58
+ ) : AddressData {
59
+ // Parse the address.
60
+ const parsed = parse_address(address)
61
+ // Assert the address type is correct.
62
+ Assert.ok(parsed.type === 'p2sh', `address type mismatch: ${parsed.type} !== ${ADDR_TYPE}`)
63
+ // Return the parsed address.
64
+ return parsed
65
+ }
@@ -0,0 +1,51 @@
1
+ import { Buff } from '@vbyte/buff'
2
+ import { Assert } from '@vbyte/micro-lib'
3
+ import { encode_address } from './encode.js'
4
+
5
+ import {
6
+ get_address_config,
7
+ parse_address
8
+ } from './util.js'
9
+
10
+ import type {
11
+ ChainNetwork,
12
+ AddressData
13
+ } from '@/types/index.js'
14
+
15
+ const ADDR_TYPE = 'p2tr'
16
+
17
+ export namespace P2TR {
18
+ export const encode = encode_p2tr_address
19
+ export const decode = decode_p2tr_address
20
+ }
21
+
22
+ function encode_p2tr_address (
23
+ pubkey : string | Uint8Array,
24
+ network : ChainNetwork = 'main'
25
+ ) : string {
26
+ // Convert the public key into bytes.
27
+ const bytes = Buff.bytes(pubkey)
28
+ // Get the address configuration.
29
+ const config = get_address_config(network, ADDR_TYPE)
30
+ // Assert the configuration exists.
31
+ Assert.exists(config, `unrecognized address config: ${ADDR_TYPE} on ${network}` )
32
+ // Assert the payload size is correct.
33
+ Assert.size(bytes, config.size, `invalid payload size: ${bytes.length} !== ${config.size}` )
34
+ // Encode the address.
35
+ return encode_address({
36
+ data : bytes,
37
+ format : 'bech32m',
38
+ prefix : config.prefix
39
+ })
40
+ }
41
+
42
+ function decode_p2tr_address (
43
+ address : string
44
+ ) : AddressData {
45
+ // Parse the address.
46
+ const parsed = parse_address(address)
47
+ // Assert the address type is correct.
48
+ Assert.ok(parsed.type === 'p2tr', `address type mismatch: ${parsed.type} !== ${ADDR_TYPE}`)
49
+ // Return the parsed address.
50
+ return parsed
51
+ }