@vbyte/btc-dev 1.1.8 → 2.1.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.
- package/CHANGELOG.md +127 -0
- package/LICENSE +21 -121
- package/README.md +69 -3
- package/dist/const.d.ts +3 -0
- package/dist/const.js +23 -22
- package/dist/error.d.ts +11 -0
- package/dist/error.js +20 -0
- package/dist/index.d.ts +12 -11
- package/dist/index.js +11 -10
- package/dist/lib/address/api.d.ts +2 -2
- package/dist/lib/address/api.js +13 -12
- package/dist/lib/address/encode.d.ts +1 -1
- package/dist/lib/address/encode.js +26 -24
- package/dist/lib/address/index.d.ts +6 -6
- package/dist/lib/address/index.js +6 -6
- package/dist/lib/address/p2pkh.d.ts +2 -2
- package/dist/lib/address/p2pkh.js +15 -15
- package/dist/lib/address/p2sh.d.ts +2 -2
- package/dist/lib/address/p2sh.js +14 -14
- package/dist/lib/address/p2tr.d.ts +2 -2
- package/dist/lib/address/p2tr.js +14 -14
- package/dist/lib/address/p2wpkh.d.ts +2 -2
- package/dist/lib/address/p2wpkh.js +15 -15
- package/dist/lib/address/p2wsh.d.ts +2 -2
- package/dist/lib/address/p2wsh.js +14 -14
- package/dist/lib/address/script.d.ts +1 -1
- package/dist/lib/address/script.js +16 -16
- package/dist/lib/address/util.d.ts +1 -1
- package/dist/lib/address/util.js +24 -22
- package/dist/lib/meta/index.d.ts +4 -4
- package/dist/lib/meta/index.js +4 -4
- package/dist/lib/meta/locktime.d.ts +1 -1
- package/dist/lib/meta/locktime.js +13 -12
- package/dist/lib/meta/ref.js +13 -9
- package/dist/lib/meta/scribe.d.ts +2 -2
- package/dist/lib/meta/scribe.js +71 -56
- package/dist/lib/meta/sequence.d.ts +1 -1
- package/dist/lib/meta/sequence.js +21 -19
- package/dist/lib/script/decode.d.ts +2 -2
- package/dist/lib/script/decode.js +53 -17
- package/dist/lib/script/encode.d.ts +1 -1
- package/dist/lib/script/encode.js +21 -16
- package/dist/lib/script/index.d.ts +5 -13
- package/dist/lib/script/index.js +5 -14
- package/dist/lib/script/lock.d.ts +2 -2
- package/dist/lib/script/lock.js +15 -12
- package/dist/lib/script/util.js +4 -4
- package/dist/lib/script/words.js +131 -130
- package/dist/lib/sighash/index.d.ts +3 -3
- package/dist/lib/sighash/index.js +3 -3
- package/dist/lib/sighash/segwit.d.ts +2 -2
- package/dist/lib/sighash/segwit.js +18 -14
- package/dist/lib/sighash/taproot.d.ts +2 -2
- package/dist/lib/sighash/taproot.js +27 -23
- package/dist/lib/sighash/util.d.ts +2 -2
- package/dist/lib/sighash/util.js +8 -7
- package/dist/lib/signer/index.d.ts +2 -2
- package/dist/lib/signer/index.js +2 -2
- package/dist/lib/signer/sign.d.ts +1 -1
- package/dist/lib/signer/sign.js +43 -7
- package/dist/lib/signer/verify.d.ts +17 -3
- package/dist/lib/signer/verify.js +232 -3
- package/dist/lib/taproot/cblock.d.ts +1 -1
- package/dist/lib/taproot/cblock.js +16 -17
- package/dist/lib/taproot/encode.d.ts +1 -1
- package/dist/lib/taproot/encode.js +9 -8
- package/dist/lib/taproot/index.d.ts +4 -4
- package/dist/lib/taproot/index.js +4 -4
- package/dist/lib/taproot/parse.d.ts +1 -1
- package/dist/lib/taproot/parse.js +15 -15
- package/dist/lib/taproot/tree.d.ts +2 -2
- package/dist/lib/taproot/tree.js +12 -7
- package/dist/lib/tx/create.d.ts +1 -1
- package/dist/lib/tx/create.js +28 -12
- package/dist/lib/tx/decode.d.ts +2 -2
- package/dist/lib/tx/decode.js +52 -17
- package/dist/lib/tx/encode.d.ts +2 -2
- package/dist/lib/tx/encode.js +13 -16
- package/dist/lib/tx/index.d.ts +7 -7
- package/dist/lib/tx/index.js +7 -7
- package/dist/lib/tx/parse.d.ts +1 -1
- package/dist/lib/tx/parse.js +9 -9
- package/dist/lib/tx/size.d.ts +2 -2
- package/dist/lib/tx/size.js +9 -11
- package/dist/lib/tx/util.d.ts +2 -2
- package/dist/lib/tx/util.js +22 -20
- package/dist/lib/tx/validate.d.ts +1 -1
- package/dist/lib/tx/validate.js +37 -9
- package/dist/lib/witness/index.d.ts +2 -2
- package/dist/lib/witness/index.js +2 -2
- package/dist/lib/witness/parse.d.ts +2 -2
- package/dist/lib/witness/parse.js +24 -23
- package/dist/lib/witness/util.d.ts +2 -2
- package/dist/lib/witness/util.js +5 -5
- package/dist/main.cjs +3305 -2035
- package/dist/main.cjs.map +1 -1
- package/dist/module.mjs +3303 -2036
- package/dist/module.mjs.map +1 -1
- package/dist/package.json +24 -19
- package/dist/schema/base.d.ts +1 -1
- package/dist/schema/base.js +17 -13
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +2 -2
- package/dist/schema/taproot.d.ts +1 -1
- package/dist/schema/taproot.js +2 -2
- package/dist/schema/tx.d.ts +1 -1
- package/dist/schema/tx.js +4 -4
- package/dist/script.js +10 -12
- package/dist/script.js.map +1 -1
- package/dist/types/address.d.ts +4 -4
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.js +8 -8
- package/dist/types/meta.d.ts +4 -4
- package/dist/types/psbt.d.ts +2 -2
- package/dist/types/script.d.ts +2 -2
- package/dist/types/sighash.d.ts +2 -2
- package/dist/types/witness.d.ts +5 -5
- package/docs/API.md +1145 -0
- package/docs/CONVENTIONS.md +316 -0
- package/docs/FAQ.md +396 -0
- package/docs/GUIDE.md +1102 -0
- package/package.json +24 -19
- package/src/const.ts +0 -61
- package/src/index.ts +0 -13
- package/src/lib/address/api.ts +0 -50
- package/src/lib/address/encode.ts +0 -183
- package/src/lib/address/index.ts +0 -7
- package/src/lib/address/p2pkh.ts +0 -94
- package/src/lib/address/p2sh.ts +0 -96
- package/src/lib/address/p2tr.ts +0 -91
- package/src/lib/address/p2wpkh.ts +0 -94
- package/src/lib/address/p2wsh.ts +0 -92
- package/src/lib/address/script.ts +0 -63
- package/src/lib/address/util.ts +0 -87
- package/src/lib/meta/index.ts +0 -4
- package/src/lib/meta/locktime.ts +0 -57
- package/src/lib/meta/ref.ts +0 -107
- package/src/lib/meta/scribe.ts +0 -256
- package/src/lib/meta/sequence.ts +0 -146
- package/src/lib/script/decode.ts +0 -85
- package/src/lib/script/encode.ts +0 -129
- package/src/lib/script/index.ts +0 -20
- package/src/lib/script/lock.ts +0 -73
- package/src/lib/script/util.ts +0 -78
- package/src/lib/script/words.ts +0 -182
- package/src/lib/sighash/index.ts +0 -3
- package/src/lib/sighash/segwit.ts +0 -152
- package/src/lib/sighash/taproot.ts +0 -206
- package/src/lib/sighash/util.ts +0 -51
- package/src/lib/signer/index.ts +0 -2
- package/src/lib/signer/sign.ts +0 -39
- package/src/lib/signer/verify.ts +0 -88
- package/src/lib/taproot/cblock.ts +0 -96
- package/src/lib/taproot/encode.ts +0 -49
- package/src/lib/taproot/index.ts +0 -4
- package/src/lib/taproot/parse.ts +0 -65
- package/src/lib/taproot/tree.ts +0 -94
- package/src/lib/tx/create.ts +0 -90
- package/src/lib/tx/decode.ts +0 -123
- package/src/lib/tx/encode.ts +0 -155
- package/src/lib/tx/index.ts +0 -7
- package/src/lib/tx/parse.ts +0 -69
- package/src/lib/tx/size.ts +0 -68
- package/src/lib/tx/util.ts +0 -111
- package/src/lib/tx/validate.ts +0 -49
- package/src/lib/witness/index.ts +0 -2
- package/src/lib/witness/parse.ts +0 -127
- package/src/lib/witness/util.ts +0 -18
- package/src/schema/base.ts +0 -57
- package/src/schema/index.ts +0 -2
- package/src/schema/taproot.ts +0 -12
- package/src/schema/tx.ts +0 -48
- package/src/types/address.ts +0 -35
- package/src/types/index.ts +0 -8
- package/src/types/meta.ts +0 -48
- package/src/types/psbt.ts +0 -15
- package/src/types/script.ts +0 -18
- package/src/types/sighash.ts +0 -16
- package/src/types/taproot.ts +0 -41
- package/src/types/txdata.ts +0 -85
- package/src/types/witness.ts +0 -42
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vbyte/btc-dev",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Batteries-included toolset for plebian bitcoin development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"taproot"
|
|
13
13
|
],
|
|
14
14
|
"author": "Christopher Scott",
|
|
15
|
-
"license": "
|
|
15
|
+
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "https://github.com/cmdruid/btc-dev.git"
|
|
@@ -24,8 +24,9 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"README.md",
|
|
26
26
|
"LICENSE",
|
|
27
|
+
"CHANGELOG.md",
|
|
27
28
|
"dist",
|
|
28
|
-
"
|
|
29
|
+
"docs"
|
|
29
30
|
],
|
|
30
31
|
"main": "./dist/main.cjs",
|
|
31
32
|
"module": "./dist/index.js",
|
|
@@ -33,9 +34,9 @@
|
|
|
33
34
|
"types": "./dist/types/index.d.ts",
|
|
34
35
|
"exports": {
|
|
35
36
|
".": {
|
|
37
|
+
"types": "./dist/types/index.d.ts",
|
|
36
38
|
"import": "./dist/index.js",
|
|
37
|
-
"default": "./dist/index.js"
|
|
38
|
-
"types": "./dist/index.d.ts"
|
|
39
|
+
"default": "./dist/index.js"
|
|
39
40
|
},
|
|
40
41
|
"./address": {
|
|
41
42
|
"types": "./dist/lib/address/index.d.ts",
|
|
@@ -72,34 +73,38 @@
|
|
|
72
73
|
},
|
|
73
74
|
"scripts": {
|
|
74
75
|
"build": "./scripts/build.sh",
|
|
75
|
-
"
|
|
76
|
+
"check": "npx tsc --project tsconfig.json --noEmit",
|
|
77
|
+
"lint": "biome check src/",
|
|
78
|
+
"package": "npm test && npm run build",
|
|
76
79
|
"release": "./scripts/release.sh",
|
|
77
80
|
"scratch": "npm run script test/scratch.ts",
|
|
78
81
|
"script": "tsx --tsconfig ./test/tsconfig.json",
|
|
79
82
|
"test": "npm run script test/src/tape.ts"
|
|
80
83
|
},
|
|
81
84
|
"dependencies": {
|
|
82
|
-
"@
|
|
83
|
-
"@
|
|
84
|
-
"@
|
|
85
|
-
"@vbyte/
|
|
86
|
-
"
|
|
87
|
-
"zod": "^4.1.5"
|
|
85
|
+
"@scure/btc-signer": "2.0.1",
|
|
86
|
+
"@vbyte/buff": "^1.1.0",
|
|
87
|
+
"@vbyte/crypto": "^1.0.1",
|
|
88
|
+
"@vbyte/util": "^2.0.0",
|
|
89
|
+
"zod": "^4.3.6"
|
|
88
90
|
},
|
|
89
91
|
"devDependencies": {
|
|
92
|
+
"@biomejs/biome": "2.3.13",
|
|
90
93
|
"@cmdcode/core-cmd": "^1.6.5",
|
|
91
|
-
"@
|
|
94
|
+
"@noble/curves": "^2.0.1",
|
|
95
|
+
"@noble/hashes": "^2.0.1",
|
|
96
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
92
97
|
"@rollup/plugin-json": "^6.1.0",
|
|
93
|
-
"@rollup/plugin-node-resolve": "^16.0.
|
|
98
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
94
99
|
"@rollup/plugin-terser": "^0.4.4",
|
|
95
|
-
"@rollup/plugin-typescript": "^12.
|
|
96
|
-
"@types/node": "^
|
|
100
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
101
|
+
"@types/node": "^25.0.10",
|
|
97
102
|
"@types/tape": "^5.8.1",
|
|
98
103
|
"faucet": "^0.0.4",
|
|
99
|
-
"rollup": "^4.
|
|
104
|
+
"rollup": "^4.56.0",
|
|
100
105
|
"tape": "^5.9.0",
|
|
101
106
|
"tslib": "^2.8.1",
|
|
102
|
-
"tsx": "^4.
|
|
103
|
-
"typescript": "^5.9.
|
|
107
|
+
"tsx": "^4.21.0",
|
|
108
|
+
"typescript": "^5.9.3"
|
|
104
109
|
}
|
|
105
110
|
}
|
package/src/const.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
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_TYPE = {
|
|
24
|
-
P2PKH : 'p2pkh',
|
|
25
|
-
P2SH : 'p2sh',
|
|
26
|
-
P2WPKH : 'p2wpkh',
|
|
27
|
-
P2WSH : 'p2wsh',
|
|
28
|
-
P2TR : 'p2tr',
|
|
29
|
-
OPRETURN : 'opreturn',
|
|
30
|
-
} as const
|
|
31
|
-
|
|
32
|
-
export const SPEND_SCRIPT_TYPE = {
|
|
33
|
-
P2PKH : 'p2pkh',
|
|
34
|
-
P2SH : 'p2sh',
|
|
35
|
-
P2WPKH : 'p2wpkh',
|
|
36
|
-
P2WSH : 'p2wsh',
|
|
37
|
-
P2TR : 'p2tr',
|
|
38
|
-
P2TS : 'p2ts',
|
|
39
|
-
} as const
|
|
40
|
-
|
|
41
|
-
export const LOCK_SCRIPT_REGEX : Record<string, RegExp> = {
|
|
42
|
-
[LOCK_SCRIPT_TYPE.P2PKH] : /^76a914[0-9a-f]{40}88ac$/i,
|
|
43
|
-
[LOCK_SCRIPT_TYPE.P2SH] : /^a914[0-9a-f]{40}87$/i,
|
|
44
|
-
[LOCK_SCRIPT_TYPE.P2WPKH] : /^0014[0-9a-f]{40}$/i,
|
|
45
|
-
[LOCK_SCRIPT_TYPE.P2WSH] : /^0020[0-9a-f]{64}$/i,
|
|
46
|
-
[LOCK_SCRIPT_TYPE.P2TR] : /^5120[0-9a-f]{64}$/i,
|
|
47
|
-
[LOCK_SCRIPT_TYPE.OPRETURN] : /^6a[0-9a-f]{2,}$/i,
|
|
48
|
-
} as const
|
|
49
|
-
|
|
50
|
-
export const SCRIPT_INT_KEY = ''
|
|
51
|
-
|
|
52
|
-
export const TX_SIZE = {
|
|
53
|
-
GLOBAL_BASE : 8,
|
|
54
|
-
GLOBAL_WIT : 10,
|
|
55
|
-
TXIN_BASE : 32 + 4 + 4,
|
|
56
|
-
TXOUT_BASE : 8,
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export const SIGHASH_DEFAULT = 0x01
|
|
60
|
-
export const SIGHASH_SEGWIT = [ 0x01, 0x02, 0x03, 0x81, 0x82, 0x83 ]
|
|
61
|
-
export const SIGHASH_TAPROOT = [ 0x00, ...SIGHASH_SEGWIT ]
|
package/src/index.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export * as ADDRESS from './lib/address/index.js'
|
|
2
|
-
export * as META from './lib/meta/index.js'
|
|
3
|
-
export * as SCRIPT from './lib/script/index.js'
|
|
4
|
-
export * as SIGHASH from './lib/sighash/index.js'
|
|
5
|
-
export * as SIGNER from './lib/signer/index.js'
|
|
6
|
-
export * as TAPROOT from './lib/taproot/index.js'
|
|
7
|
-
export * as TX from './lib/tx/index.js'
|
|
8
|
-
export * as WITNESS from './lib/witness/index.js'
|
|
9
|
-
|
|
10
|
-
export * as CONST from './const.js'
|
|
11
|
-
export * as SCHEMA from './schema/index.js'
|
|
12
|
-
|
|
13
|
-
export type * from './types/index.js'
|
package/src/lib/address/api.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Buff, Bytes } from '@vbyte/buff'
|
|
2
|
-
import { get_lock_script_type } from '@/lib/script/lock.js'
|
|
3
|
-
import { get_address_info } from './util.js'
|
|
4
|
-
import { LOCK_SCRIPT_TYPE } from '@/const.js'
|
|
5
|
-
|
|
6
|
-
import { P2PKH } from './p2pkh.js'
|
|
7
|
-
import { P2SH } from './p2sh.js'
|
|
8
|
-
import { P2TR } from './p2tr.js'
|
|
9
|
-
import { P2WPKH } from './p2wpkh.js'
|
|
10
|
-
import { P2WSH } from './p2wsh.js'
|
|
11
|
-
|
|
12
|
-
import type { AddressInfo, ChainNetwork } from '@/types/index.js'
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Get the address for a given locking script.
|
|
16
|
-
*
|
|
17
|
-
* @param script - The locking script.
|
|
18
|
-
* @param network - The network to use.
|
|
19
|
-
* @returns The address.
|
|
20
|
-
*/
|
|
21
|
-
export function get_address (
|
|
22
|
-
script : Bytes,
|
|
23
|
-
network : ChainNetwork = 'main'
|
|
24
|
-
) : string {
|
|
25
|
-
// Convert the script into bytes.
|
|
26
|
-
const bytes = Buff.bytes(script)
|
|
27
|
-
// Get the address configuration.
|
|
28
|
-
const type = get_lock_script_type(bytes)
|
|
29
|
-
// If the script type is not recognized, throw an error.
|
|
30
|
-
if (type === null) throw new Error('unknown locking script: ' + bytes.hex)
|
|
31
|
-
// Create the address based on the script type.
|
|
32
|
-
switch (type) {
|
|
33
|
-
case LOCK_SCRIPT_TYPE.P2PKH:
|
|
34
|
-
return P2PKH.encode_address(script, network)
|
|
35
|
-
case LOCK_SCRIPT_TYPE.P2SH:
|
|
36
|
-
return P2SH.encode_address(script, network)
|
|
37
|
-
case LOCK_SCRIPT_TYPE.P2WPKH:
|
|
38
|
-
return P2WPKH.encode_address(script, network)
|
|
39
|
-
case LOCK_SCRIPT_TYPE.P2WSH:
|
|
40
|
-
return P2WSH.encode_address(script, network)
|
|
41
|
-
case LOCK_SCRIPT_TYPE.P2TR:
|
|
42
|
-
return P2TR.encode_address(script, network)
|
|
43
|
-
default:
|
|
44
|
-
throw new Error('unknown script type: ' + type)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function parse_address (address : string) : AddressInfo {
|
|
49
|
-
return get_address_info(address)
|
|
50
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { Buff } from '@vbyte/buff'
|
|
2
|
-
|
|
3
|
-
import { Assert, B58chk, Bech32, Bech32m } from '@vbyte/micro-lib'
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
AddressFormat,
|
|
7
|
-
EncoderConfig,
|
|
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) : EncoderConfig {
|
|
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 : EncoderConfig
|
|
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 : EncoderConfig) : 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) : EncoderConfig {
|
|
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 : EncoderConfig) : 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) : EncoderConfig {
|
|
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 : EncoderConfig) : 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) : EncoderConfig {
|
|
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
|
-
}
|
package/src/lib/address/index.ts
DELETED
package/src/lib/address/p2pkh.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Buff, Bytes } 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
|
-
import { is_p2pkh_script } from '@/lib/script/lock.js'
|
|
6
|
-
import { LOCK_SCRIPT_TYPE } from '@/const.js'
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
get_address_config,
|
|
10
|
-
get_address_info
|
|
11
|
-
} from './util.js'
|
|
12
|
-
|
|
13
|
-
import type {
|
|
14
|
-
AddressInfo,
|
|
15
|
-
ChainNetwork
|
|
16
|
-
} from '@/types/index.js'
|
|
17
|
-
|
|
18
|
-
const ADDRESS_TYPE = LOCK_SCRIPT_TYPE.P2PKH
|
|
19
|
-
|
|
20
|
-
export namespace P2PKH {
|
|
21
|
-
export const create_address = create_p2pkh_address
|
|
22
|
-
export const create_script = create_p2pkh_script
|
|
23
|
-
export const encode_address = encode_p2pkh_address
|
|
24
|
-
export const encode_script = encode_p2pkh_script
|
|
25
|
-
export const decode_address = decode_p2pkh_address
|
|
26
|
-
export const decode_script = decode_p2pkh_script
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function create_p2pkh_address (
|
|
30
|
-
pubkey : Bytes,
|
|
31
|
-
network : ChainNetwork = 'main',
|
|
32
|
-
) : string {
|
|
33
|
-
// Create the p2pkh script.
|
|
34
|
-
const script = create_p2pkh_script(pubkey)
|
|
35
|
-
// Encode the script as an address.
|
|
36
|
-
return encode_p2pkh_address(script, network)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function create_p2pkh_script (pubkey : Bytes) : Buff {
|
|
40
|
-
// Convert the public key into bytes.
|
|
41
|
-
const bytes = Buff.bytes(pubkey)
|
|
42
|
-
// Assert the public key is 33 bytes.
|
|
43
|
-
Assert.size(bytes, 33, 'invalid pubkey size')
|
|
44
|
-
// Convert the bytes into a hash.
|
|
45
|
-
const hash = hash160(bytes)
|
|
46
|
-
// Return the script.
|
|
47
|
-
return encode_p2pkh_script(hash)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function encode_p2pkh_script (pk_hash : Bytes) : Buff {
|
|
51
|
-
return Buff.join([ '76a914', pk_hash, '88ac' ])
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function encode_p2pkh_address (
|
|
55
|
-
script : Bytes,
|
|
56
|
-
network : ChainNetwork = 'main',
|
|
57
|
-
) : string {
|
|
58
|
-
// Get the public key hash from the script.
|
|
59
|
-
const pk_hash = decode_p2pkh_script(script)
|
|
60
|
-
// Get the address configuration.
|
|
61
|
-
const config = get_address_config(network, ADDRESS_TYPE)
|
|
62
|
-
// Assert the configuration exists.
|
|
63
|
-
Assert.exists(config, `unrecognized address config: ${ADDRESS_TYPE} on ${network}` )
|
|
64
|
-
// Assert the payload size is correct.
|
|
65
|
-
Assert.size(pk_hash, config.size, `invalid payload size: ${pk_hash.length} !== ${config.size}` )
|
|
66
|
-
// Encode the address.
|
|
67
|
-
return encode_address({
|
|
68
|
-
data : pk_hash,
|
|
69
|
-
format : 'base58',
|
|
70
|
-
version : config.version
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function decode_p2pkh_address (
|
|
75
|
-
address : string
|
|
76
|
-
) : AddressInfo {
|
|
77
|
-
// Parse the address.
|
|
78
|
-
const parsed = get_address_info(address)
|
|
79
|
-
// Assert the address type is correct.
|
|
80
|
-
Assert.ok(parsed.type === 'p2pkh', `address type mismatch: ${parsed.type} !== ${ADDRESS_TYPE}`)
|
|
81
|
-
// Return the parsed address.
|
|
82
|
-
return parsed
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function decode_p2pkh_script (
|
|
86
|
-
script : Bytes,
|
|
87
|
-
) : Buff {
|
|
88
|
-
// Convert the script into bytes.
|
|
89
|
-
const bytes = Buff.bytes(script)
|
|
90
|
-
// Assert the script is a p2pkh script.
|
|
91
|
-
Assert.ok(is_p2pkh_script(script), `invalid p2pkh script`)
|
|
92
|
-
// Return the public key hash from the script.
|
|
93
|
-
return bytes.slice(3, 23)
|
|
94
|
-
}
|
package/src/lib/address/p2sh.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { Buff, Bytes } 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
|
-
import { is_p2sh_script } from '@/lib/script/lock.js'
|
|
6
|
-
import { LOCK_SCRIPT_TYPE } from '@/const.js'
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
get_address_config,
|
|
10
|
-
get_address_info
|
|
11
|
-
} from './util.js'
|
|
12
|
-
|
|
13
|
-
import type {
|
|
14
|
-
AddressInfo,
|
|
15
|
-
ChainNetwork
|
|
16
|
-
} from '@/types/index.js'
|
|
17
|
-
|
|
18
|
-
const ADDRESS_TYPE = LOCK_SCRIPT_TYPE.P2SH
|
|
19
|
-
|
|
20
|
-
export namespace P2SH {
|
|
21
|
-
export const create_address = create_p2sh_address
|
|
22
|
-
export const create_script = create_p2sh_script
|
|
23
|
-
export const encode_address = encode_p2sh_address
|
|
24
|
-
export const encode_script = encode_p2sh_script
|
|
25
|
-
export const decode_address = decode_p2sh_address
|
|
26
|
-
export const decode_script = decode_p2sh_script
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function create_p2sh_address (
|
|
30
|
-
script : Bytes,
|
|
31
|
-
network : ChainNetwork = 'main',
|
|
32
|
-
) : string {
|
|
33
|
-
// Convert the script into bytes.
|
|
34
|
-
const bytes = Buff.bytes(script)
|
|
35
|
-
// Convert the bytes into a hash.
|
|
36
|
-
const hash = hash160(bytes)
|
|
37
|
-
// Create the p2sh script.
|
|
38
|
-
const p2sh_script = encode_p2sh_script(hash)
|
|
39
|
-
// Encode the address.
|
|
40
|
-
return encode_p2sh_address(p2sh_script, network)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function create_p2sh_script (script : Bytes) : Buff {
|
|
44
|
-
// Convert the script into bytes.
|
|
45
|
-
const bytes = Buff.bytes(script)
|
|
46
|
-
// Convert the bytes into a hash.
|
|
47
|
-
const hash = hash160(bytes)
|
|
48
|
-
// Return the script.
|
|
49
|
-
return encode_p2sh_script(hash)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function encode_p2sh_script (script_hash : Bytes) : Buff {
|
|
53
|
-
return Buff.join([ 'a914', script_hash, '87' ])
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function encode_p2sh_address (
|
|
57
|
-
script_pk : Bytes,
|
|
58
|
-
network : ChainNetwork = 'main',
|
|
59
|
-
) : string {
|
|
60
|
-
// Get the script hash from the script.
|
|
61
|
-
const script_hash = decode_p2sh_script(script_pk)
|
|
62
|
-
// Get the address configuration.
|
|
63
|
-
const config = get_address_config(network, ADDRESS_TYPE)
|
|
64
|
-
// Assert the configuration exists.
|
|
65
|
-
Assert.exists(config, `unrecognized address config: ${ADDRESS_TYPE} on ${network}` )
|
|
66
|
-
// Assert the payload size is correct.
|
|
67
|
-
Assert.size(script_hash, config.size, `invalid payload size: ${script_hash.length} !== ${config.size}` )
|
|
68
|
-
// Encode the address.
|
|
69
|
-
return encode_address({
|
|
70
|
-
data : script_hash,
|
|
71
|
-
format : 'base58',
|
|
72
|
-
version : config.version
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function decode_p2sh_address (
|
|
77
|
-
address : string
|
|
78
|
-
) : AddressInfo {
|
|
79
|
-
// Parse the address.
|
|
80
|
-
const parsed = get_address_info(address)
|
|
81
|
-
// Assert the address type is correct.
|
|
82
|
-
Assert.ok(parsed.type === 'p2sh', `address type mismatch: ${parsed.type} !== ${ADDRESS_TYPE}`)
|
|
83
|
-
// Return the parsed address.
|
|
84
|
-
return parsed
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function decode_p2sh_script (
|
|
88
|
-
script : Bytes,
|
|
89
|
-
) : Buff {
|
|
90
|
-
// Assert the script is a p2sh script.
|
|
91
|
-
Assert.ok(is_p2sh_script(script), `invalid p2sh script`)
|
|
92
|
-
// Convert the script into bytes.
|
|
93
|
-
const bytes = Buff.bytes(script)
|
|
94
|
-
// Return the script hash from the script.
|
|
95
|
-
return bytes.slice(2, 22)
|
|
96
|
-
}
|
package/src/lib/address/p2tr.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { Buff, Bytes } from '@vbyte/buff'
|
|
2
|
-
import { Assert } from '@vbyte/micro-lib'
|
|
3
|
-
import { encode_address } from './encode.js'
|
|
4
|
-
import { is_p2tr_script } from '@/lib/script/lock.js'
|
|
5
|
-
import { LOCK_SCRIPT_TYPE } from '@/const.js'
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
get_address_config,
|
|
9
|
-
get_address_info
|
|
10
|
-
} from './util.js'
|
|
11
|
-
|
|
12
|
-
import type {
|
|
13
|
-
AddressInfo,
|
|
14
|
-
ChainNetwork
|
|
15
|
-
} from '@/types/index.js'
|
|
16
|
-
|
|
17
|
-
const ADDRESS_TYPE = LOCK_SCRIPT_TYPE.P2TR
|
|
18
|
-
|
|
19
|
-
export namespace P2TR {
|
|
20
|
-
export const create_address = create_p2tr_address
|
|
21
|
-
export const create_script = create_p2tr_script
|
|
22
|
-
export const encode_address = encode_p2tr_address
|
|
23
|
-
export const encode_script = encode_p2tr_script
|
|
24
|
-
export const decode_address = decode_p2tr_address
|
|
25
|
-
export const decode_script = decode_p2tr_script
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function create_p2tr_address (
|
|
29
|
-
pubkey : Bytes,
|
|
30
|
-
network : ChainNetwork = 'main',
|
|
31
|
-
) : string {
|
|
32
|
-
// Create the p2tr script.
|
|
33
|
-
const script = create_p2tr_script(pubkey)
|
|
34
|
-
// Encode the script as an address.
|
|
35
|
-
return encode_p2tr_address(script, network)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function create_p2tr_script (pubkey : Bytes) : Buff {
|
|
39
|
-
// Convert the public key into bytes.
|
|
40
|
-
const bytes = Buff.bytes(pubkey)
|
|
41
|
-
// Assert the public key is 32 bytes.
|
|
42
|
-
Assert.size(bytes, 32, 'invalid pubkey size')
|
|
43
|
-
// Return the script.
|
|
44
|
-
return encode_p2tr_script(bytes)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function encode_p2tr_script (pubkey : Bytes) : Buff {
|
|
48
|
-
return Buff.join([ '5120', pubkey ])
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function encode_p2tr_address (
|
|
52
|
-
script_pk : Bytes,
|
|
53
|
-
network : ChainNetwork = 'main'
|
|
54
|
-
) : string {
|
|
55
|
-
// Get the public key from the script.
|
|
56
|
-
const pubkey = decode_p2tr_script(script_pk)
|
|
57
|
-
// Get the address configuration.
|
|
58
|
-
const config = get_address_config(network, ADDRESS_TYPE)
|
|
59
|
-
// Assert the configuration exists.
|
|
60
|
-
Assert.exists(config, `unrecognized address config: ${ADDRESS_TYPE} on ${network}` )
|
|
61
|
-
// Assert the payload size is correct.
|
|
62
|
-
Assert.size(pubkey, config.size, `invalid payload size: ${pubkey.length} !== ${config.size}` )
|
|
63
|
-
// Encode the address.
|
|
64
|
-
return encode_address({
|
|
65
|
-
data : pubkey,
|
|
66
|
-
format : 'bech32m',
|
|
67
|
-
prefix : config.prefix
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function decode_p2tr_address (
|
|
72
|
-
address : string
|
|
73
|
-
) : AddressInfo {
|
|
74
|
-
// Parse the address.
|
|
75
|
-
const parsed = get_address_info(address)
|
|
76
|
-
// Assert the address type is correct.
|
|
77
|
-
Assert.ok(parsed.type === 'p2tr', `address type mismatch: ${parsed.type} !== ${ADDRESS_TYPE}`)
|
|
78
|
-
// Return the parsed address.
|
|
79
|
-
return parsed
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function decode_p2tr_script (
|
|
83
|
-
script : Bytes,
|
|
84
|
-
) : Buff {
|
|
85
|
-
// Assert the script is a p2tr script.
|
|
86
|
-
Assert.ok(is_p2tr_script(script), `invalid p2tr script`)
|
|
87
|
-
// Convert the script into bytes.
|
|
88
|
-
const bytes = Buff.bytes(script)
|
|
89
|
-
// Return the public key from the script.
|
|
90
|
-
return bytes.slice(2, 34)
|
|
91
|
-
}
|