@vbyte/btc-dev 1.0.15 → 1.1.1

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 (48) hide show
  1. package/dist/index.d.ts +0 -1
  2. package/dist/index.js +0 -1
  3. package/dist/lib/meta/locktime.d.ts +1 -1
  4. package/dist/lib/meta/locktime.js +5 -5
  5. package/dist/lib/meta/ref.d.ts +1 -1
  6. package/dist/lib/meta/ref.js +6 -6
  7. package/dist/lib/meta/scribe.d.ts +5 -3
  8. package/dist/lib/meta/scribe.js +21 -18
  9. package/dist/lib/meta/sequence.d.ts +1 -1
  10. package/dist/lib/meta/sequence.js +5 -5
  11. package/dist/lib/script/decode.d.ts +2 -1
  12. package/dist/lib/script/encode.d.ts +1 -1
  13. package/dist/lib/script/encode.js +3 -3
  14. package/dist/lib/taproot/cblock.js +1 -0
  15. package/dist/main.cjs +100 -4036
  16. package/dist/main.cjs.map +1 -1
  17. package/dist/module.mjs +99 -4034
  18. package/dist/module.mjs.map +1 -1
  19. package/dist/package.json +5 -9
  20. package/dist/schema/tx.d.ts +12 -12
  21. package/dist/script.js +8 -8
  22. package/dist/script.js.map +1 -1
  23. package/dist/types/taproot.d.ts +1 -0
  24. package/package.json +5 -9
  25. package/src/index.ts +0 -1
  26. package/src/lib/meta/locktime.ts +1 -1
  27. package/src/lib/meta/ref.ts +1 -1
  28. package/src/lib/meta/scribe.ts +29 -24
  29. package/src/lib/meta/sequence.ts +1 -1
  30. package/src/lib/script/decode.ts +2 -2
  31. package/src/lib/script/encode.ts +4 -5
  32. package/src/lib/taproot/cblock.ts +1 -0
  33. package/src/types/taproot.ts +1 -0
  34. package/dist/lib/psbt/encoder.d.ts +0 -5
  35. package/dist/lib/psbt/encoder.js +0 -21
  36. package/dist/lib/psbt/index.d.ts +0 -4
  37. package/dist/lib/psbt/index.js +0 -4
  38. package/dist/lib/psbt/meta.d.ts +0 -3
  39. package/dist/lib/psbt/meta.js +0 -11
  40. package/dist/lib/psbt/util.d.ts +0 -5
  41. package/dist/lib/psbt/util.js +0 -44
  42. package/dist/lib/psbt/validate.d.ts +0 -2
  43. package/dist/lib/psbt/validate.js +0 -11
  44. package/src/lib/psbt/encoder.ts +0 -24
  45. package/src/lib/psbt/index.ts +0 -4
  46. package/src/lib/psbt/meta.ts +0 -15
  47. package/src/lib/psbt/util.ts +0 -62
  48. package/src/lib/psbt/validate.ts +0 -18
@@ -14,6 +14,7 @@ export interface TaprootConfig {
14
14
  export interface TaprootContext {
15
15
  cblock: string;
16
16
  int_key: string;
17
+ path: string[];
17
18
  parity: number;
18
19
  taproot: string | null;
19
20
  tapkey: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vbyte/btc-dev",
3
- "version": "1.0.15",
3
+ "version": "1.1.1",
4
4
  "description": "Batteries-included toolset for plebian bitcoin development",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -45,10 +45,6 @@
45
45
  "types": "./dist/lib/meta/index.d.ts",
46
46
  "import": "./dist/lib/meta/index.js"
47
47
  },
48
- "./psbt": {
49
- "types": "./dist/lib/psbt/index.d.ts",
50
- "import": "./dist/lib/psbt/index.js"
51
- },
52
48
  "./script": {
53
49
  "types": "./dist/lib/script/index.d.ts",
54
50
  "import": "./dist/lib/script/index.js"
@@ -87,8 +83,8 @@
87
83
  "@noble/hashes": "^1.8.0",
88
84
  "@scure/btc-signer": "^1.8.1",
89
85
  "@vbyte/buff": "^1.0.2",
90
- "@vbyte/micro-lib": "^1.0.14",
91
- "zod": "^3.25.69"
86
+ "@vbyte/micro-lib": "^1.1.1",
87
+ "zod": "^4.0.5"
92
88
  },
93
89
  "devDependencies": {
94
90
  "@cmdcode/core-cmd": "^1.6.5",
@@ -97,10 +93,10 @@
97
93
  "@rollup/plugin-node-resolve": "^16.0.1",
98
94
  "@rollup/plugin-terser": "^0.4.4",
99
95
  "@rollup/plugin-typescript": "^12.1.4",
100
- "@types/node": "^24.0.10",
96
+ "@types/node": "^24.0.14",
101
97
  "@types/tape": "^5.8.1",
102
98
  "faucet": "^0.0.4",
103
- "rollup": "^4.44.1",
99
+ "rollup": "^4.45.1",
104
100
  "tape": "^5.9.0",
105
101
  "tslib": "^2.8.1",
106
102
  "tsx": "^4.20.3",
package/src/index.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  export * as ADDRESS from './lib/address/index.js'
2
2
  export * as META from './lib/meta/index.js'
3
- export * as PSBT from './lib/psbt/index.js'
4
3
  export * as SCRIPT from './lib/script/index.js'
5
4
  export * as SIGHASH from './lib/sighash/index.js'
6
5
  export * as SIGNER from './lib/signer/index.js'
@@ -5,7 +5,7 @@ import type { LocktimeData } from '@/types/index.js'
5
5
  // The threshold between block height and timestamp.
6
6
  const LOCKTIME_THRESHOLD = 500000000
7
7
 
8
- export namespace LocktimeUtil {
8
+ export namespace LocktimeField {
9
9
  export const encode = encode_locktime
10
10
  export const decode = decode_locktime
11
11
  }
@@ -1,4 +1,4 @@
1
- export namespace RefEncoder {
1
+ export namespace RefPointer {
2
2
  export const outpoint = {
3
3
  encode : encode_outpoint,
4
4
  decode : decode_outpoint,
@@ -1,7 +1,7 @@
1
- import { Buff, Stream } from '@vbyte/buff'
2
- import { Assert } from '@vbyte/micro-lib'
3
- import { encode_script } from '@/lib/script/encode.js'
4
- import { decode_script } from '@/lib/script/decode.js'
1
+ import { Buff, Bytes, Stream } from '@vbyte/buff'
2
+ import { Assert } from '@vbyte/micro-lib'
3
+ import { encode_script } from '@/lib/script/encode.js'
4
+ import { decode_script } from '@/lib/script/decode.js'
5
5
 
6
6
  import type { InscriptionData } from '@/types/index.js'
7
7
 
@@ -9,23 +9,24 @@ const _0n = BigInt(0)
9
9
  const _1n = BigInt(1)
10
10
  const _26n = BigInt(26)
11
11
 
12
- export namespace ScribeEncoder {
12
+ export namespace InscriptionUtil {
13
+ export type Type = InscriptionData
13
14
  export const encode = encode_inscription
14
15
  export const decode = decode_inscription
15
16
  }
16
17
 
17
18
  export function decode_inscription (
18
- script : string
19
+ script : Bytes
19
20
  ) : InscriptionData[] {
20
21
  const envelopes = parse_envelopes(script)
21
22
  return envelopes.map(parse_record)
22
23
  }
23
24
 
24
- export function encode_inscription (data : InscriptionData[]) : string {
25
- return data.map(create_envelope).join('')
25
+ export function encode_inscription (data : InscriptionData[]) : Buff {
26
+ return Buff.join(data.map(create_envelope))
26
27
  }
27
28
 
28
- function create_envelope (data : InscriptionData) : string {
29
+ function create_envelope (data : InscriptionData) : Buff {
29
30
  let asm : string[] = [ 'OP_0', 'OP_IF', '6f7264' ]
30
31
 
31
32
  if (typeof data.delegate === 'string') {
@@ -73,7 +74,7 @@ function create_envelope (data : InscriptionData) : string {
73
74
  }
74
75
 
75
76
  function parse_envelopes (
76
- script : string
77
+ script : Bytes
77
78
  ) : string[][] {
78
79
 
79
80
  const words = decode_script(script)
@@ -98,7 +99,7 @@ function parse_envelopes (
98
99
  return envelopes
99
100
  }
100
101
 
101
- function parse_record (envelope : string[]) {
102
+ function parse_record (envelope : Bytes[]) {
102
103
  const record : InscriptionData = {}
103
104
 
104
105
  for (let i = 0; i < envelope.length; i++) {
@@ -124,7 +125,7 @@ function parse_record (envelope : string[]) {
124
125
  i += 1
125
126
  break
126
127
  case 'OP_WITHIN':
127
- record.ref = envelope[i+1]
128
+ record.ref = decode_bytes(envelope[i+1])
128
129
  i += 1
129
130
  break;
130
131
  case 'OP_NOP':
@@ -139,6 +140,10 @@ function parse_record (envelope : string[]) {
139
140
  return record
140
141
  }
141
142
 
143
+ function decode_bytes (bytes : Bytes) : string {
144
+ return Buff.bytes(bytes).hex
145
+ }
146
+
142
147
  function encode_id (
143
148
  identifier : string
144
149
  ) : string {
@@ -151,9 +156,9 @@ function encode_id (
151
156
  }
152
157
 
153
158
  function decode_id (
154
- hexstr : string
159
+ identifier : Bytes
155
160
  ) : string {
156
- const bytes = Buff.hex(hexstr)
161
+ const bytes = Buff.bytes(identifier)
157
162
  const idx = bytes.at(-1) ?? 0
158
163
  const txid = bytes.slice(0, -1).reverse().hex
159
164
  return txid + 'i' + String(idx)
@@ -166,9 +171,9 @@ function encode_pointer (
166
171
  }
167
172
 
168
173
  function decode_pointer (
169
- hexstr : string
174
+ bytes : Bytes
170
175
  ) : number {
171
- return Buff.hex(hexstr).reverse().num
176
+ return Buff.bytes(bytes).reverse().num
172
177
  }
173
178
 
174
179
  function encode_label (
@@ -178,9 +183,9 @@ function encode_label (
178
183
  }
179
184
 
180
185
  function decode_label (
181
- hexstr : string
186
+ label : Bytes
182
187
  ) : string {
183
- return Buff.hex(hexstr).str
188
+ return Buff.bytes(label).str
184
189
  }
185
190
 
186
191
  function encode_content (
@@ -204,11 +209,11 @@ function encode_content (
204
209
  }
205
210
 
206
211
  function decode_content (
207
- hexstrs : string[],
208
- type : 'hex' | 'utf8' = 'hex'
212
+ chunks : Bytes[],
213
+ format : 'hex' | 'utf8' = 'hex'
209
214
  ) : string {
210
- const data = Buff.join(hexstrs)
211
- return (type === 'hex')
215
+ const data = Buff.join(chunks)
216
+ return (format === 'hex')
212
217
  ? data.hex
213
218
  : data.str
214
219
  }
@@ -225,9 +230,9 @@ function encode_rune_label (label : string) : string {
225
230
  return Buff.big(big).reverse().hex
226
231
  }
227
232
 
228
- function decode_rune_label (hex: string): string {
233
+ function decode_rune_label (label: Bytes): string {
229
234
  // Convert hex to BigInt, with byte order reversed
230
- let big = Buff.hex(hex).reverse().big
235
+ let big = Buff.bytes(label).reverse().big
231
236
  // Add 1 as per the encoding algorithm
232
237
  big = big + _1n
233
238
  // Initialize result string
@@ -23,7 +23,7 @@ const TIMELOCK_GRANULARITY = 512 // Seconds per timestamp unit (BIP-68 s
23
23
 
24
24
  /* ===== [ API ] ============================================================ */
25
25
 
26
- export namespace SequenceUtil {
26
+ export namespace SequenceField {
27
27
  export const encode = encode_sequence
28
28
  export const decode = decode_sequence
29
29
  }
@@ -1,4 +1,4 @@
1
- import { Stream } from '@vbyte/buff'
1
+ import { Bytes, Stream } from '@vbyte/buff'
2
2
 
3
3
  import {
4
4
  get_op_code,
@@ -10,7 +10,7 @@ import {
10
10
  * Decode a bitcoin script into asm instructions.
11
11
  */
12
12
  export function decode_script (
13
- script : string | Uint8Array
13
+ script : Bytes
14
14
  ) : string[] {
15
15
  const stream = new Stream(script)
16
16
 
@@ -10,8 +10,8 @@ const MAX_WORD_SIZE = 520
10
10
  export function encode_script (
11
11
  words : (string | number | Uint8Array)[],
12
12
  varint = false
13
- ) : string {
14
- if (words.length === 0) return '00'
13
+ ) : Buff {
14
+ if (words.length === 0) return Buff.num(0, 1)
15
15
 
16
16
  const bytes = []
17
17
 
@@ -23,11 +23,10 @@ export function encode_script (
23
23
  const buffer = Buff.join(bytes)
24
24
 
25
25
  return (varint)
26
- ? buffer.prepend(Buff.varint(buffer.length, 'le')).hex
27
- : buffer.hex
26
+ ? buffer.prepend(Buff.varint(buffer.length, 'le'))
27
+ : buffer
28
28
  }
29
29
 
30
-
31
30
  /** Check if the word is a valid opcode,
32
31
  * and return its integer value.
33
32
  */
@@ -64,6 +64,7 @@ export function create_taproot (config : TaprootConfig) : TaprootContext {
64
64
 
65
65
  return {
66
66
  int_key : Buff.bytes(pubkey).hex,
67
+ path,
67
68
  parity,
68
69
  taproot : taproot ?? null,
69
70
  cblock : cblock.hex,
@@ -18,6 +18,7 @@ export interface TaprootConfig {
18
18
  export interface TaprootContext {
19
19
  cblock : string
20
20
  int_key : string
21
+ path : string[]
21
22
  parity : number
22
23
  taproot : string | null
23
24
  tapkey : string
@@ -1,5 +0,0 @@
1
- import { Transaction } from '@scure/btc-signer';
2
- import type { PSBTData } from '../../types/index.js';
3
- export declare function decode_psbt(b64str: string): Transaction;
4
- export declare function encode_psbt(psbt: PSBTData): string;
5
- export declare function parse_psbt(psbt: string | PSBTData): Transaction;
@@ -1,21 +0,0 @@
1
- import { Base64 } from '@vbyte/micro-lib';
2
- import { Transaction } from '@scure/btc-signer';
3
- export function decode_psbt(b64str) {
4
- const psbt = Base64.decode(b64str);
5
- return Transaction.fromPSBT(psbt, { allowUnknownOutputs: true });
6
- }
7
- export function encode_psbt(psbt) {
8
- const psbt_bytes = psbt.toPSBT(0);
9
- return Base64.encode(psbt_bytes);
10
- }
11
- export function parse_psbt(psbt) {
12
- if (psbt instanceof Transaction) {
13
- return psbt;
14
- }
15
- else if (typeof psbt === 'string') {
16
- return decode_psbt(psbt);
17
- }
18
- else {
19
- throw new Error('invalid psbt input: ' + psbt);
20
- }
21
- }
@@ -1,4 +0,0 @@
1
- export * from './encoder.js';
2
- export * from './meta.js';
3
- export * from './util.js';
4
- export * from './validate.js';
@@ -1,4 +0,0 @@
1
- export * from './encoder.js';
2
- export * from './meta.js';
3
- export * from './util.js';
4
- export * from './validate.js';
@@ -1,3 +0,0 @@
1
- import { PSBTData } from '../../types/index.js';
2
- export declare function get_vsize(psbt: string | PSBTData): number;
3
- export declare function get_txhex(psbt: PSBTData): string;
@@ -1,11 +0,0 @@
1
- import { parse_psbt } from './encoder.js';
2
- import { finalize_legacy_inputs } from './util.js';
3
- export function get_vsize(psbt) {
4
- const pdata = parse_psbt(psbt);
5
- return pdata.vsize;
6
- }
7
- export function get_txhex(psbt) {
8
- let pdata = parse_psbt(psbt);
9
- pdata = finalize_legacy_inputs(pdata);
10
- return pdata.hex;
11
- }
@@ -1,5 +0,0 @@
1
- import type { PSBTData, PSBTInput, PSBTOutput, PSBTPrevouts } from '../../types/index.js';
2
- export declare function collect_vins(psbt: string | PSBTData): PSBTInput[];
3
- export declare function collect_vouts(psbt: string | PSBTData): PSBTOutput[];
4
- export declare function collect_prevouts(psbt: PSBTData): PSBTPrevouts;
5
- export declare function finalize_legacy_inputs(pdata: PSBTData): import("node_modules/@scure/btc-signer/transaction.js").Transaction;
@@ -1,44 +0,0 @@
1
- import { Assert } from '@vbyte/micro-lib';
2
- import { parse_psbt } from './encoder.js';
3
- export function collect_vins(psbt) {
4
- const pdata = parse_psbt(psbt);
5
- const count = pdata.inputsLength;
6
- const vins = [];
7
- for (let i = 0; i < count; i++) {
8
- const vin = pdata.getInput(i);
9
- vins.push(vin);
10
- }
11
- return vins;
12
- }
13
- export function collect_vouts(psbt) {
14
- const pdata = parse_psbt(psbt);
15
- const count = pdata.outputsLength;
16
- const vouts = [];
17
- for (let i = 0; i < count; i++) {
18
- const vout = pdata.getOutput(i);
19
- vouts.push(vout);
20
- }
21
- return vouts;
22
- }
23
- export function collect_prevouts(psbt) {
24
- const amounts = [], scripts = [];
25
- const pdata = parse_psbt(psbt);
26
- for (let i = 0; i < pdata.inputsLength; i++) {
27
- const txin = pdata.getInput(i);
28
- Assert.exists(txin.witnessUtxo, `witness utxo does not exist for input ${i}`);
29
- amounts.push(txin.witnessUtxo.amount);
30
- scripts.push(txin.witnessUtxo.script);
31
- }
32
- return { amounts, scripts };
33
- }
34
- export function finalize_legacy_inputs(pdata) {
35
- for (let i = 0; i < pdata.inputsLength; i++) {
36
- const pvin = pdata.getInput(i);
37
- const script = pvin.redeemScript;
38
- const psig = pvin.partialSig?.at(0);
39
- if (script !== undefined && psig !== undefined) {
40
- pdata.finalizeIdx(i);
41
- }
42
- }
43
- return pdata;
44
- }
@@ -1,2 +0,0 @@
1
- import type { PSBTData } from '../../types/index.js';
2
- export declare function assert_psbt_is_funded(psbt: string | PSBTData): void;
@@ -1,11 +0,0 @@
1
- import { Assert } from '@vbyte/micro-lib';
2
- import { parse_psbt } from './encoder.js';
3
- import { collect_vins, collect_vouts } from './util.js';
4
- export function assert_psbt_is_funded(psbt) {
5
- const pdata = parse_psbt(psbt);
6
- const pvouts = collect_vins(pdata);
7
- const txouts = collect_vouts(pdata);
8
- const vin_amt = pvouts.reduce((p, n) => p + Number(n.witnessUtxo?.amount ?? 0), 0);
9
- const out_amt = txouts.reduce((p, n) => p + Number(n.amount ?? 0), 0);
10
- Assert.ok(vin_amt >= out_amt, `value in (${vin_amt}) < value out (${out_amt})`);
11
- }
@@ -1,24 +0,0 @@
1
- import { Base64 } from '@vbyte/micro-lib'
2
- import { Transaction } from '@scure/btc-signer'
3
-
4
- import type { PSBTData } from '@/types/index.js'
5
-
6
- export function decode_psbt (b64str : string) : Transaction {
7
- const psbt = Base64.decode(b64str)
8
- return Transaction.fromPSBT(psbt, { allowUnknownOutputs: true })
9
- }
10
-
11
- export function encode_psbt (psbt : PSBTData) : string {
12
- const psbt_bytes = psbt.toPSBT(0)
13
- return Base64.encode(psbt_bytes)
14
- }
15
-
16
- export function parse_psbt (psbt : string | PSBTData) : Transaction {
17
- if (psbt instanceof Transaction) {
18
- return psbt
19
- } else if (typeof psbt === 'string') {
20
- return decode_psbt(psbt)
21
- } else {
22
- throw new Error('invalid psbt input: ' + psbt)
23
- }
24
- }
@@ -1,4 +0,0 @@
1
- export * from './encoder.js'
2
- export * from './meta.js'
3
- export * from './util.js'
4
- export * from './validate.js'
@@ -1,15 +0,0 @@
1
- import { parse_psbt } from './encoder.js'
2
- import { finalize_legacy_inputs } from './util.js'
3
-
4
- import { PSBTData } from '@/types/index.js'
5
-
6
- export function get_vsize (psbt : string | PSBTData) : number {
7
- const pdata = parse_psbt(psbt)
8
- return pdata.vsize
9
- }
10
-
11
- export function get_txhex (psbt : PSBTData) : string {
12
- let pdata = parse_psbt(psbt)
13
- pdata = finalize_legacy_inputs(pdata)
14
- return pdata.hex
15
- }
@@ -1,62 +0,0 @@
1
- import { Assert } from '@vbyte/micro-lib'
2
- import { parse_psbt } from './encoder.js'
3
-
4
- import type {
5
- PSBTData,
6
- PSBTInput,
7
- PSBTOutput,
8
- PSBTPrevouts
9
- } from '@/types/index.js'
10
-
11
- export function collect_vins (
12
- psbt : string | PSBTData
13
- ) : PSBTInput[] {
14
- const pdata = parse_psbt(psbt)
15
- const count = pdata.inputsLength
16
- const vins : PSBTInput[] = []
17
- for (let i = 0; i < count; i++) {
18
- const vin = pdata.getInput(i)
19
- vins.push(vin)
20
- }
21
- return vins
22
- }
23
-
24
- export function collect_vouts (
25
- psbt : string | PSBTData
26
- ) : PSBTOutput[] {
27
- const pdata = parse_psbt(psbt)
28
- const count = pdata.outputsLength
29
- const vouts : PSBTOutput[] = []
30
- for (let i = 0; i < count; i++) {
31
- const vout = pdata.getOutput(i)
32
- vouts.push(vout)
33
- }
34
- return vouts
35
- }
36
-
37
- export function collect_prevouts (
38
- psbt : PSBTData
39
- ) : PSBTPrevouts {
40
- const amounts : bigint[] = [],
41
- scripts : Uint8Array[] = []
42
- const pdata = parse_psbt(psbt)
43
- for (let i = 0; i < pdata.inputsLength; i++) {
44
- const txin = pdata.getInput(i)
45
- Assert.exists(txin.witnessUtxo, `witness utxo does not exist for input ${i}`)
46
- amounts.push(txin.witnessUtxo.amount)
47
- scripts.push(txin.witnessUtxo.script)
48
- }
49
- return { amounts, scripts }
50
- }
51
-
52
- export function finalize_legacy_inputs (pdata : PSBTData) {
53
- for (let i = 0; i < pdata.inputsLength; i++) {
54
- const pvin = pdata.getInput(i)
55
- const script = pvin.redeemScript
56
- const psig = pvin.partialSig?.at(0)
57
- if (script !== undefined && psig !== undefined) {
58
- pdata.finalizeIdx(i)
59
- }
60
- }
61
- return pdata
62
- }
@@ -1,18 +0,0 @@
1
- import { Assert } from '@vbyte/micro-lib'
2
- import { parse_psbt } from './encoder.js'
3
-
4
- import {
5
- collect_vins,
6
- collect_vouts
7
- } from './util.js'
8
-
9
- import type { PSBTData } from '@/types/index.js'
10
-
11
- export function assert_psbt_is_funded (psbt : string | PSBTData) : void {
12
- const pdata = parse_psbt(psbt)
13
- const pvouts = collect_vins(pdata)
14
- const txouts = collect_vouts(pdata)
15
- const vin_amt = pvouts.reduce((p, n) => p + Number(n.witnessUtxo?.amount ?? 0), 0)
16
- const out_amt = txouts.reduce((p, n) => p + Number(n.amount ?? 0), 0)
17
- Assert.ok(vin_amt >= out_amt, `value in (${vin_amt}) < value out (${out_amt})`)
18
- }