@secondlayer/stacks 4.3.1 → 5.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.
- package/README.md +27 -11
- package/dist/shared/{stacks-gxq2pbky.js → stacks-2as26bcg.js} +10 -7
- package/dist/shared/stacks-2as26bcg.js.map +13 -0
- package/dist/shared/{stacks-bfan7ex7.js → stacks-4d7c3x27.js} +5 -5
- package/dist/shared/{stacks-bfan7ex7.js.map → stacks-4d7c3x27.js.map} +3 -3
- package/dist/shared/{stacks-709tra19.js → stacks-4hs8r4q2.js} +16 -2
- package/dist/shared/stacks-4hs8r4q2.js.map +10 -0
- package/dist/shared/{stacks-w23294am.js → stacks-51ybf135.js} +3 -3
- package/dist/shared/{stacks-0jk7vd8r.cjs → stacks-69nq48jp.js} +120 -17
- package/dist/shared/stacks-69nq48jp.js.map +15 -0
- package/dist/shared/{stacks-8pfdscq6.js → stacks-6gavarmy.js} +37 -9
- package/dist/shared/stacks-6gavarmy.js.map +12 -0
- package/dist/shared/{stacks-7wkf2rph.js → stacks-7bqkf3b0.js} +86 -71
- package/dist/shared/{stacks-7wkf2rph.js.map → stacks-7bqkf3b0.js.map} +9 -10
- package/dist/shared/{stacks-zcpvzbr0.js → stacks-8brgfvqx.js} +3 -3
- package/dist/shared/{stacks-4vzmhw3q.cjs → stacks-8vzxax5e.cjs} +13 -3
- package/dist/shared/stacks-8vzxax5e.cjs.map +10 -0
- package/dist/shared/{stacks-hnqt5rz4.js → stacks-9c1yam8b.js} +3 -3
- package/dist/shared/{stacks-bnbdqznq.cjs → stacks-bdgh9n83.cjs} +11 -10
- package/dist/shared/{stacks-bnbdqznq.cjs.map → stacks-bdgh9n83.cjs.map} +3 -3
- package/dist/shared/{stacks-fb75yew8.js → stacks-db3kwavg.cjs} +346 -138
- package/dist/shared/stacks-db3kwavg.cjs.map +23 -0
- package/dist/shared/{stacks-jpt52csy.js → stacks-e3nwm1dz.js} +14 -17
- package/dist/shared/stacks-e3nwm1dz.js.map +10 -0
- package/dist/shared/{stacks-27fmgajb.js → stacks-ga026yxz.js} +9 -9
- package/dist/shared/{stacks-27fmgajb.js.map → stacks-ga026yxz.js.map} +3 -3
- package/dist/shared/{stacks-nyaw1z2a.cjs → stacks-ggdz96r1.cjs} +4 -4
- package/dist/shared/{stacks-nyaw1z2a.cjs.map → stacks-ggdz96r1.cjs.map} +3 -3
- package/dist/shared/{stacks-08y0y0t7.js → stacks-gjz26k6b.js} +2 -2
- package/dist/shared/{stacks-x5386y2y.cjs → stacks-gza2n1zs.cjs} +5 -5
- package/dist/shared/{stacks-x5386y2y.cjs.map → stacks-gza2n1zs.cjs.map} +3 -3
- package/dist/shared/{stacks-ta1gar0b.cjs → stacks-kqn4y8kq.cjs} +7 -5
- package/dist/shared/{stacks-ta1gar0b.cjs.map → stacks-kqn4y8kq.cjs.map} +3 -3
- package/dist/shared/{stacks-ztzygy90.js → stacks-mftyrc60.js} +2 -2
- package/dist/shared/stacks-n4d8j8q3.js +801 -0
- package/dist/shared/stacks-n4d8j8q3.js.map +23 -0
- package/dist/shared/{stacks-ycbq8pf7.cjs → stacks-p337hp6m.cjs} +74 -59
- package/dist/shared/{stacks-ycbq8pf7.cjs.map → stacks-p337hp6m.cjs.map} +9 -10
- package/dist/shared/{stacks-ttdk2g2f.js → stacks-s5vej5z6.cjs} +92 -41
- package/dist/shared/stacks-s5vej5z6.cjs.map +15 -0
- package/dist/shared/stacks-sdqkapct.cjs +67 -0
- package/dist/shared/stacks-sdqkapct.cjs.map +12 -0
- package/dist/shared/{stacks-1arrcd11.js → stacks-v2rfr46a.js} +2 -2
- package/dist/shared/{stacks-9mqveyjv.cjs → stacks-w9t61fra.cjs} +7 -10
- package/dist/shared/stacks-w9t61fra.cjs.map +10 -0
- package/dist/shared/{stacks-tjjnkt3r.js → stacks-wxfd6r4b.js} +2 -2
- package/dist/shared/{stacks-4z72akdf.js → stacks-x0qqwrev.js} +3 -3
- package/dist/shared/{stacks-gck1sq7h.cjs → stacks-xjkn3en1.cjs} +16 -2
- package/dist/shared/stacks-xjkn3en1.cjs.map +10 -0
- package/dist/shared/stacks-xnrywjf1.cjs +131 -0
- package/dist/shared/stacks-xnrywjf1.cjs.map +11 -0
- package/dist/shared/stacks-yajyej2y.js +139 -0
- package/dist/shared/stacks-yajyej2y.js.map +11 -0
- package/dist/shared/{stacks-913a2rx7.js → stacks-yvb7rvwk.js} +13 -3
- package/dist/shared/stacks-yvb7rvwk.js.map +10 -0
- package/dist/shared/{stacks-0cdm20eh.js → stacks-z90xdr1x.js} +7 -11
- package/dist/shared/{stacks-0cdm20eh.js.map → stacks-z90xdr1x.js.map} +3 -3
- package/dist/src/accounts/index.js +2 -3
- package/dist/src/accounts/index.js.map +2 -2
- package/dist/src/actions/index.cjs +2 -1
- package/dist/src/actions/index.cjs.map +1 -1
- package/dist/src/actions/index.d.cts +108 -20
- package/dist/src/actions/index.d.ts +108 -20
- package/dist/src/actions/index.js +17 -15
- package/dist/src/actions/index.js.map +1 -1
- package/dist/src/bitcoin/index.d.cts +27 -0
- package/dist/src/bitcoin/index.d.ts +27 -0
- package/dist/src/bitcoin/index.js +10 -11
- package/dist/src/bitcoin/index.js.map +2 -2
- package/dist/src/bns/index.d.cts +27 -0
- package/dist/src/bns/index.d.ts +27 -0
- package/dist/src/bns/index.js +13 -13
- package/dist/src/bns/index.js.map +1 -1
- package/dist/src/clarity/index.js +7 -6
- package/dist/src/clarity/index.js.map +1 -1
- package/dist/src/connect/index.cjs +44 -30
- package/dist/src/connect/index.cjs.map +7 -7
- package/dist/src/connect/index.d.cts +16 -1
- package/dist/src/connect/index.d.ts +16 -1
- package/dist/src/connect/index.js +44 -30
- package/dist/src/connect/index.js.map +7 -7
- package/dist/src/connect/walletconnect/index.cjs +49 -413
- package/dist/src/connect/walletconnect/index.cjs.map +4 -4
- package/dist/src/connect/walletconnect/index.js +47 -411
- package/dist/src/connect/walletconnect/index.js.map +4 -4
- package/dist/src/filters/index.js +2 -2
- package/dist/src/index.cjs +49 -124
- package/dist/src/index.cjs.map +6 -8
- package/dist/src/index.d.cts +163 -54
- package/dist/src/index.d.ts +163 -54
- package/dist/src/index.js +79 -147
- package/dist/src/index.js.map +6 -8
- package/dist/src/postconditions/index.js +6 -5
- package/dist/src/postconditions/index.js.map +1 -1
- package/dist/src/pox/index.cjs +7 -83
- package/dist/src/pox/index.cjs.map +3 -3
- package/dist/src/pox/index.d.cts +32 -1
- package/dist/src/pox/index.d.ts +32 -1
- package/dist/src/pox/index.js +22 -102
- package/dist/src/pox/index.js.map +3 -3
- package/dist/src/pox5/index.cjs +4 -129
- package/dist/src/pox5/index.cjs.map +3 -4
- package/dist/src/pox5/index.d.cts +27 -0
- package/dist/src/pox5/index.d.ts +27 -0
- package/dist/src/pox5/index.js +20 -148
- package/dist/src/pox5/index.js.map +3 -4
- package/dist/src/sbtc/index.cjs +2 -59
- package/dist/src/sbtc/index.cjs.map +3 -3
- package/dist/src/sbtc/index.d.cts +30 -2
- package/dist/src/sbtc/index.d.ts +30 -2
- package/dist/src/sbtc/index.js +15 -74
- package/dist/src/sbtc/index.js.map +3 -3
- package/dist/src/stackingdao/index.d.cts +27 -0
- package/dist/src/stackingdao/index.d.ts +27 -0
- package/dist/src/stackingdao/index.js +11 -11
- package/dist/src/stackingdao/index.js.map +1 -1
- package/dist/src/subscriptions/index.d.cts +27 -0
- package/dist/src/subscriptions/index.d.ts +27 -0
- package/dist/src/subscriptions/index.js +2 -2
- package/dist/src/tools/btc/index.cjs.map +2 -2
- package/dist/src/tools/btc/index.js.map +2 -2
- package/dist/src/tools/index.cjs +629 -392
- package/dist/src/tools/index.cjs.map +30 -28
- package/dist/src/tools/index.d.cts +44 -0
- package/dist/src/tools/index.d.ts +44 -0
- package/dist/src/tools/index.js +628 -391
- package/dist/src/tools/index.js.map +30 -28
- package/dist/src/transactions/index.js +6 -5
- package/dist/src/transactions/index.js.map +1 -1
- package/dist/src/utils/index.d.cts +2 -5
- package/dist/src/utils/index.d.ts +2 -5
- package/dist/src/utils/index.js +2 -2
- package/package.json +18 -7
- package/dist/shared/stacks-0eatsx6d.cjs +0 -25
- package/dist/shared/stacks-0eatsx6d.cjs.map +0 -10
- package/dist/shared/stacks-0jk7vd8r.cjs.map +0 -14
- package/dist/shared/stacks-4vzmhw3q.cjs.map +0 -10
- package/dist/shared/stacks-5nmz5ad9.js +0 -409
- package/dist/shared/stacks-5nmz5ad9.js.map +0 -10
- package/dist/shared/stacks-709tra19.js.map +0 -10
- package/dist/shared/stacks-8pfdscq6.js.map +0 -12
- package/dist/shared/stacks-913a2rx7.js.map +0 -10
- package/dist/shared/stacks-9mqveyjv.cjs.map +0 -10
- package/dist/shared/stacks-e4xn4m7j.js +0 -27
- package/dist/shared/stacks-e4xn4m7j.js.map +0 -10
- package/dist/shared/stacks-fb75yew8.js.map +0 -21
- package/dist/shared/stacks-gck1sq7h.cjs.map +0 -10
- package/dist/shared/stacks-gxq2pbky.js.map +0 -13
- package/dist/shared/stacks-jpt52csy.js.map +0 -10
- package/dist/shared/stacks-mnnhpex3.cjs +0 -407
- package/dist/shared/stacks-mnnhpex3.cjs.map +0 -10
- package/dist/shared/stacks-tdsp5gsb.cjs +0 -527
- package/dist/shared/stacks-tdsp5gsb.cjs.map +0 -21
- package/dist/shared/stacks-ttdk2g2f.js.map +0 -14
- package/dist/shared/stacks-wdp5yr8n.cjs +0 -39
- package/dist/shared/stacks-wdp5yr8n.cjs.map +0 -12
- /package/dist/shared/{stacks-w23294am.js.map → stacks-51ybf135.js.map} +0 -0
- /package/dist/shared/{stacks-zcpvzbr0.js.map → stacks-8brgfvqx.js.map} +0 -0
- /package/dist/shared/{stacks-hnqt5rz4.js.map → stacks-9c1yam8b.js.map} +0 -0
- /package/dist/shared/{stacks-08y0y0t7.js.map → stacks-gjz26k6b.js.map} +0 -0
- /package/dist/shared/{stacks-ztzygy90.js.map → stacks-mftyrc60.js.map} +0 -0
- /package/dist/shared/{stacks-1arrcd11.js.map → stacks-v2rfr46a.js.map} +0 -0
- /package/dist/shared/{stacks-tjjnkt3r.js.map → stacks-wxfd6r4b.js.map} +0 -0
- /package/dist/shared/{stacks-4z72akdf.js.map → stacks-x0qqwrev.js.map} +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/pox/constants.ts
|
|
2
|
+
var POX_CONTRACTS = {
|
|
3
|
+
mainnet: {
|
|
4
|
+
address: "SP000000000000000000002Q6VF78",
|
|
5
|
+
name: "pox-4"
|
|
6
|
+
},
|
|
7
|
+
testnet: {
|
|
8
|
+
address: "ST000000000000000000002AMW42H",
|
|
9
|
+
name: "pox-4"
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var MIN_LOCK_PERIOD = 1;
|
|
13
|
+
var MAX_LOCK_PERIOD = 12;
|
|
14
|
+
var POX_ADDRESS_VERSION = {
|
|
15
|
+
p2pkh: 0,
|
|
16
|
+
p2sh: 1,
|
|
17
|
+
p2sh_p2wpkh: 2,
|
|
18
|
+
p2sh_p2wsh: 3,
|
|
19
|
+
p2wpkh: 4,
|
|
20
|
+
p2wsh: 5,
|
|
21
|
+
p2tr: 6
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/pox5/btcAddress.ts
|
|
25
|
+
var import_base = require("@scure/base");
|
|
26
|
+
function expectedHashLen(version) {
|
|
27
|
+
if (!Number.isInteger(version) || version < 0 || version > 6) {
|
|
28
|
+
throw new Error(`Unknown PoX address version: 0x${version.toString(16)}`);
|
|
29
|
+
}
|
|
30
|
+
return version <= 4 ? 20 : 32;
|
|
31
|
+
}
|
|
32
|
+
function canonicalizeBtcAddress(repr) {
|
|
33
|
+
const expected = expectedHashLen(repr.version);
|
|
34
|
+
const { hashbytes } = repr;
|
|
35
|
+
if (hashbytes.length === expected)
|
|
36
|
+
return { version: repr.version, hashbytes };
|
|
37
|
+
if (expected === 20 && hashbytes.length === 32 && hashbytes.slice(20).every((b) => b === 0)) {
|
|
38
|
+
return { version: repr.version, hashbytes: hashbytes.slice(0, 20) };
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Invalid hashbytes length for PoX version 0x${repr.version.toString(16)}: ${hashbytes.length}`);
|
|
41
|
+
}
|
|
42
|
+
function parseBtcAddress(address) {
|
|
43
|
+
if (address.startsWith("bc1") || address.startsWith("tb1") || address.startsWith("bcrt1")) {
|
|
44
|
+
return parseSegwitAddress(address);
|
|
45
|
+
}
|
|
46
|
+
return parseLegacyAddress(address);
|
|
47
|
+
}
|
|
48
|
+
function parseSegwitAddress(address) {
|
|
49
|
+
let decoded;
|
|
50
|
+
try {
|
|
51
|
+
decoded = import_base.bech32.decode(address);
|
|
52
|
+
} catch {
|
|
53
|
+
decoded = import_base.bech32m.decode(address);
|
|
54
|
+
}
|
|
55
|
+
const witnessVersion = decoded.words[0];
|
|
56
|
+
if (witnessVersion === undefined) {
|
|
57
|
+
throw new Error("Invalid segwit address: missing witness version");
|
|
58
|
+
}
|
|
59
|
+
const data = import_base.bech32.fromWords(decoded.words.slice(1));
|
|
60
|
+
const hashbytes = new Uint8Array(data);
|
|
61
|
+
let version;
|
|
62
|
+
if (witnessVersion === 0) {
|
|
63
|
+
if (hashbytes.length === 20) {
|
|
64
|
+
version = POX_ADDRESS_VERSION.p2wpkh;
|
|
65
|
+
} else if (hashbytes.length === 32) {
|
|
66
|
+
version = POX_ADDRESS_VERSION.p2wsh;
|
|
67
|
+
} else {
|
|
68
|
+
throw new Error(`Invalid witness v0 program length: ${hashbytes.length}`);
|
|
69
|
+
}
|
|
70
|
+
} else if (witnessVersion === 1) {
|
|
71
|
+
if (hashbytes.length !== 32) {
|
|
72
|
+
throw new Error(`Invalid witness v1 program length: ${hashbytes.length}`);
|
|
73
|
+
}
|
|
74
|
+
version = POX_ADDRESS_VERSION.p2tr;
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(`Unsupported witness version: ${witnessVersion}`);
|
|
77
|
+
}
|
|
78
|
+
return { version, hashbytes };
|
|
79
|
+
}
|
|
80
|
+
function parseLegacyAddress(address) {
|
|
81
|
+
const decoded = import_base.base58.decode(address);
|
|
82
|
+
if (decoded.length !== 25) {
|
|
83
|
+
throw new Error(`Invalid legacy address length: ${decoded.length}`);
|
|
84
|
+
}
|
|
85
|
+
const versionByte = decoded[0];
|
|
86
|
+
if (versionByte === undefined) {
|
|
87
|
+
throw new Error("Invalid legacy address: missing version byte");
|
|
88
|
+
}
|
|
89
|
+
const payload = decoded.slice(0, 21);
|
|
90
|
+
const checksum = decoded.slice(21);
|
|
91
|
+
const expected = doubleSha256(payload).slice(0, 4);
|
|
92
|
+
if (checksum.length !== 4 || expected.some((b, i) => b !== checksum[i])) {
|
|
93
|
+
throw new Error("Invalid legacy address checksum");
|
|
94
|
+
}
|
|
95
|
+
const hashbytes = decoded.slice(1, 21);
|
|
96
|
+
let version;
|
|
97
|
+
if (versionByte === 0 || versionByte === 111) {
|
|
98
|
+
version = POX_ADDRESS_VERSION.p2pkh;
|
|
99
|
+
} else if (versionByte === 5 || versionByte === 196) {
|
|
100
|
+
version = POX_ADDRESS_VERSION.p2sh;
|
|
101
|
+
} else {
|
|
102
|
+
throw new Error(`Unknown legacy address version byte: 0x${versionByte.toString(16)}`);
|
|
103
|
+
}
|
|
104
|
+
return { version, hashbytes };
|
|
105
|
+
}
|
|
106
|
+
function stringifyBtcAddress(repr, network) {
|
|
107
|
+
const { version, hashbytes } = canonicalizeBtcAddress(repr);
|
|
108
|
+
const params = BITCOIN_NETWORK_PARAMS[network];
|
|
109
|
+
switch (version) {
|
|
110
|
+
case POX_ADDRESS_VERSION.p2pkh:
|
|
111
|
+
return base58CheckEncode(params.p2pkh, hashbytes);
|
|
112
|
+
case POX_ADDRESS_VERSION.p2sh:
|
|
113
|
+
case POX_ADDRESS_VERSION.p2sh_p2wpkh:
|
|
114
|
+
case POX_ADDRESS_VERSION.p2sh_p2wsh:
|
|
115
|
+
return base58CheckEncode(params.p2sh, hashbytes);
|
|
116
|
+
case POX_ADDRESS_VERSION.p2wpkh:
|
|
117
|
+
case POX_ADDRESS_VERSION.p2wsh:
|
|
118
|
+
return import_base.bech32.encode(params.hrp, [0, ...import_base.bech32.toWords(hashbytes)]);
|
|
119
|
+
case POX_ADDRESS_VERSION.p2tr:
|
|
120
|
+
return import_base.bech32m.encode(params.hrp, [1, ...import_base.bech32m.toWords(hashbytes)]);
|
|
121
|
+
default:
|
|
122
|
+
throw new Error(`Unknown PoX address version: 0x${version.toString(16)}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
var BtcAddress = {
|
|
126
|
+
parse: parseBtcAddress,
|
|
127
|
+
stringify: stringifyBtcAddress
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
//# debugId=F00DD70BC680A86264756E2164756E21
|
|
131
|
+
//# sourceMappingURL=stacks-xnrywjf1.cjs.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/pox/constants.ts", "../src/pox5/btcAddress.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export const POX_CONTRACTS = {\n\tmainnet: {\n\t\taddress: \"SP000000000000000000002Q6VF78\",\n\t\tname: \"pox-4\",\n\t},\n\ttestnet: {\n\t\taddress: \"ST000000000000000000002AMW42H\",\n\t\tname: \"pox-4\",\n\t},\n} as const;\n\nexport const MIN_LOCK_PERIOD = 1;\nexport const MAX_LOCK_PERIOD = 12;\n\n/** PoX address version bytes (maps to Bitcoin address types) */\nexport const POX_ADDRESS_VERSION = {\n\t/** P2PKH - legacy addresses starting with \"1\" */\n\tp2pkh: 0x00,\n\t/** P2SH - script hash addresses starting with \"3\" */\n\tp2sh: 0x01,\n\t/** P2SH-P2WPKH - nested segwit */\n\tp2sh_p2wpkh: 0x02,\n\t/** P2SH-P2WSH - nested segwit script */\n\tp2sh_p2wsh: 0x03,\n\t/** P2WPKH - native segwit \"bc1q\" (20-byte hash) */\n\tp2wpkh: 0x04,\n\t/** P2WSH - native segwit \"bc1q\" (32-byte hash) */\n\tp2wsh: 0x05,\n\t/** P2TR - taproot \"bc1p\" (32-byte key) */\n\tp2tr: 0x06,\n} as const;\n",
|
|
6
|
+
"import { base58, bech32, bech32m } from \"@scure/base\";\nimport {\n\tBITCOIN_NETWORK_PARAMS,\n\tbase58CheckEncode,\n} from \"../bitcoin/address.ts\";\nimport type { BitcoinNetwork } from \"../bitcoin/constants.ts\";\nimport { doubleSha256 } from \"../bitcoin/serialize.ts\";\nimport { POX_ADDRESS_VERSION } from \"../pox/constants.ts\";\n\n/**\n * SIP-005 PoX `pox-addr` tuple, decoded from a Bitcoin address. `version` is\n * the PoX byte (`POX_ADDRESS_VERSION`), not a Bitcoin network version\n * (`p2sh` is 0x01 here, 0x05 on mainnet Bitcoin). `hashbytes` is the 20- or\n * 32-byte payload — unpadded, matching `check-pox-addr-hashbytes`.\n */\nexport type BtcAddressRepr = {\n\tversion: number;\n\thashbytes: Uint8Array;\n};\n\nfunction expectedHashLen(version: number): number {\n\tif (!Number.isInteger(version) || version < 0x00 || version > 0x06) {\n\t\tthrow new Error(`Unknown PoX address version: 0x${version.toString(16)}`);\n\t}\n\treturn version <= 0x04 ? 20 : 32;\n}\n\n/** Strip frozen-pox 32-byte padding; reject a length that doesn't match the version. */\nexport function canonicalizeBtcAddress(repr: BtcAddressRepr): BtcAddressRepr {\n\tconst expected = expectedHashLen(repr.version);\n\tconst { hashbytes } = repr;\n\tif (hashbytes.length === expected)\n\t\treturn { version: repr.version, hashbytes };\n\tif (\n\t\texpected === 20 &&\n\t\thashbytes.length === 32 &&\n\t\thashbytes.slice(20).every((b) => b === 0)\n\t) {\n\t\treturn { version: repr.version, hashbytes: hashbytes.slice(0, 20) };\n\t}\n\tthrow new Error(\n\t\t`Invalid hashbytes length for PoX version 0x${repr.version.toString(16)}: ${hashbytes.length}`,\n\t);\n}\n\n/**\n * Parse a Bitcoin address string into a PoX address tuple.\n * Supports P2PKH, P2SH, P2WPKH, P2WSH, P2TR (mainnet, testnet, regtest).\n */\nexport function parseBtcAddress(address: string): BtcAddressRepr {\n\tif (\n\t\taddress.startsWith(\"bc1\") ||\n\t\taddress.startsWith(\"tb1\") ||\n\t\taddress.startsWith(\"bcrt1\")\n\t) {\n\t\treturn parseSegwitAddress(address);\n\t}\n\treturn parseLegacyAddress(address);\n}\n\nfunction parseSegwitAddress(address: string): BtcAddressRepr {\n\tlet decoded: { prefix: string; words: number[] };\n\ttry {\n\t\tdecoded = bech32.decode(address as `${string}1${string}`);\n\t} catch {\n\t\tdecoded = bech32m.decode(address as `${string}1${string}`);\n\t}\n\n\tconst witnessVersion = decoded.words[0];\n\tif (witnessVersion === undefined) {\n\t\tthrow new Error(\"Invalid segwit address: missing witness version\");\n\t}\n\tconst data = bech32.fromWords(decoded.words.slice(1));\n\tconst hashbytes = new Uint8Array(data);\n\n\tlet version: number;\n\tif (witnessVersion === 0) {\n\t\tif (hashbytes.length === 20) {\n\t\t\tversion = POX_ADDRESS_VERSION.p2wpkh;\n\t\t} else if (hashbytes.length === 32) {\n\t\t\tversion = POX_ADDRESS_VERSION.p2wsh;\n\t\t} else {\n\t\t\tthrow new Error(`Invalid witness v0 program length: ${hashbytes.length}`);\n\t\t}\n\t} else if (witnessVersion === 1) {\n\t\tif (hashbytes.length !== 32) {\n\t\t\tthrow new Error(`Invalid witness v1 program length: ${hashbytes.length}`);\n\t\t}\n\t\tversion = POX_ADDRESS_VERSION.p2tr;\n\t} else {\n\t\tthrow new Error(`Unsupported witness version: ${witnessVersion}`);\n\t}\n\n\treturn { version, hashbytes };\n}\n\nfunction parseLegacyAddress(address: string): BtcAddressRepr {\n\tconst decoded = base58.decode(address);\n\n\tif (decoded.length !== 25) {\n\t\tthrow new Error(`Invalid legacy address length: ${decoded.length}`);\n\t}\n\n\tconst versionByte = decoded[0];\n\tif (versionByte === undefined) {\n\t\tthrow new Error(\"Invalid legacy address: missing version byte\");\n\t}\n\tconst payload = decoded.slice(0, 21);\n\tconst checksum = decoded.slice(21);\n\tconst expected = doubleSha256(payload).slice(0, 4);\n\tif (checksum.length !== 4 || expected.some((b, i) => b !== checksum[i])) {\n\t\tthrow new Error(\"Invalid legacy address checksum\");\n\t}\n\tconst hashbytes = decoded.slice(1, 21);\n\n\tlet version: number;\n\tif (versionByte === 0x00 || versionByte === 0x6f) {\n\t\tversion = POX_ADDRESS_VERSION.p2pkh;\n\t} else if (versionByte === 0x05 || versionByte === 0xc4) {\n\t\tversion = POX_ADDRESS_VERSION.p2sh;\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Unknown legacy address version byte: 0x${versionByte.toString(16)}`,\n\t\t);\n\t}\n\n\treturn { version, hashbytes };\n}\n\nexport function stringifyBtcAddress(\n\trepr: BtcAddressRepr,\n\tnetwork: BitcoinNetwork,\n): string {\n\tconst { version, hashbytes } = canonicalizeBtcAddress(repr);\n\tconst params = BITCOIN_NETWORK_PARAMS[network];\n\tswitch (version) {\n\t\tcase POX_ADDRESS_VERSION.p2pkh:\n\t\t\treturn base58CheckEncode(params.p2pkh, hashbytes);\n\t\tcase POX_ADDRESS_VERSION.p2sh:\n\t\tcase POX_ADDRESS_VERSION.p2sh_p2wpkh:\n\t\tcase POX_ADDRESS_VERSION.p2sh_p2wsh:\n\t\t\treturn base58CheckEncode(params.p2sh, hashbytes);\n\t\tcase POX_ADDRESS_VERSION.p2wpkh:\n\t\tcase POX_ADDRESS_VERSION.p2wsh:\n\t\t\treturn bech32.encode(params.hrp, [0, ...bech32.toWords(hashbytes)]);\n\t\tcase POX_ADDRESS_VERSION.p2tr:\n\t\t\treturn bech32m.encode(params.hrp, [1, ...bech32m.toWords(hashbytes)]);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown PoX address version: 0x${version.toString(16)}`);\n\t}\n}\n\nexport const BtcAddress: {\n\tparse: typeof parseBtcAddress;\n\tstringify: typeof stringifyBtcAddress;\n} = {\n\tparse: parseBtcAddress,\n\tstringify: stringifyBtcAddress,\n};\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "F00DD70BC680A86264756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BITCOIN_NETWORK_PARAMS,
|
|
3
|
+
base58CheckEncode,
|
|
4
|
+
doubleSha256
|
|
5
|
+
} from "./stacks-z90xdr1x.js";
|
|
6
|
+
|
|
7
|
+
// src/pox/constants.ts
|
|
8
|
+
var POX_CONTRACTS = {
|
|
9
|
+
mainnet: {
|
|
10
|
+
address: "SP000000000000000000002Q6VF78",
|
|
11
|
+
name: "pox-4"
|
|
12
|
+
},
|
|
13
|
+
testnet: {
|
|
14
|
+
address: "ST000000000000000000002AMW42H",
|
|
15
|
+
name: "pox-4"
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var MIN_LOCK_PERIOD = 1;
|
|
19
|
+
var MAX_LOCK_PERIOD = 12;
|
|
20
|
+
var POX_ADDRESS_VERSION = {
|
|
21
|
+
p2pkh: 0,
|
|
22
|
+
p2sh: 1,
|
|
23
|
+
p2sh_p2wpkh: 2,
|
|
24
|
+
p2sh_p2wsh: 3,
|
|
25
|
+
p2wpkh: 4,
|
|
26
|
+
p2wsh: 5,
|
|
27
|
+
p2tr: 6
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/pox5/btcAddress.ts
|
|
31
|
+
import { base58, bech32, bech32m } from "@scure/base";
|
|
32
|
+
function expectedHashLen(version) {
|
|
33
|
+
if (!Number.isInteger(version) || version < 0 || version > 6) {
|
|
34
|
+
throw new Error(`Unknown PoX address version: 0x${version.toString(16)}`);
|
|
35
|
+
}
|
|
36
|
+
return version <= 4 ? 20 : 32;
|
|
37
|
+
}
|
|
38
|
+
function canonicalizeBtcAddress(repr) {
|
|
39
|
+
const expected = expectedHashLen(repr.version);
|
|
40
|
+
const { hashbytes } = repr;
|
|
41
|
+
if (hashbytes.length === expected)
|
|
42
|
+
return { version: repr.version, hashbytes };
|
|
43
|
+
if (expected === 20 && hashbytes.length === 32 && hashbytes.slice(20).every((b) => b === 0)) {
|
|
44
|
+
return { version: repr.version, hashbytes: hashbytes.slice(0, 20) };
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`Invalid hashbytes length for PoX version 0x${repr.version.toString(16)}: ${hashbytes.length}`);
|
|
47
|
+
}
|
|
48
|
+
function parseBtcAddress(address) {
|
|
49
|
+
if (address.startsWith("bc1") || address.startsWith("tb1") || address.startsWith("bcrt1")) {
|
|
50
|
+
return parseSegwitAddress(address);
|
|
51
|
+
}
|
|
52
|
+
return parseLegacyAddress(address);
|
|
53
|
+
}
|
|
54
|
+
function parseSegwitAddress(address) {
|
|
55
|
+
let decoded;
|
|
56
|
+
try {
|
|
57
|
+
decoded = bech32.decode(address);
|
|
58
|
+
} catch {
|
|
59
|
+
decoded = bech32m.decode(address);
|
|
60
|
+
}
|
|
61
|
+
const witnessVersion = decoded.words[0];
|
|
62
|
+
if (witnessVersion === undefined) {
|
|
63
|
+
throw new Error("Invalid segwit address: missing witness version");
|
|
64
|
+
}
|
|
65
|
+
const data = bech32.fromWords(decoded.words.slice(1));
|
|
66
|
+
const hashbytes = new Uint8Array(data);
|
|
67
|
+
let version;
|
|
68
|
+
if (witnessVersion === 0) {
|
|
69
|
+
if (hashbytes.length === 20) {
|
|
70
|
+
version = POX_ADDRESS_VERSION.p2wpkh;
|
|
71
|
+
} else if (hashbytes.length === 32) {
|
|
72
|
+
version = POX_ADDRESS_VERSION.p2wsh;
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error(`Invalid witness v0 program length: ${hashbytes.length}`);
|
|
75
|
+
}
|
|
76
|
+
} else if (witnessVersion === 1) {
|
|
77
|
+
if (hashbytes.length !== 32) {
|
|
78
|
+
throw new Error(`Invalid witness v1 program length: ${hashbytes.length}`);
|
|
79
|
+
}
|
|
80
|
+
version = POX_ADDRESS_VERSION.p2tr;
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error(`Unsupported witness version: ${witnessVersion}`);
|
|
83
|
+
}
|
|
84
|
+
return { version, hashbytes };
|
|
85
|
+
}
|
|
86
|
+
function parseLegacyAddress(address) {
|
|
87
|
+
const decoded = base58.decode(address);
|
|
88
|
+
if (decoded.length !== 25) {
|
|
89
|
+
throw new Error(`Invalid legacy address length: ${decoded.length}`);
|
|
90
|
+
}
|
|
91
|
+
const versionByte = decoded[0];
|
|
92
|
+
if (versionByte === undefined) {
|
|
93
|
+
throw new Error("Invalid legacy address: missing version byte");
|
|
94
|
+
}
|
|
95
|
+
const payload = decoded.slice(0, 21);
|
|
96
|
+
const checksum = decoded.slice(21);
|
|
97
|
+
const expected = doubleSha256(payload).slice(0, 4);
|
|
98
|
+
if (checksum.length !== 4 || expected.some((b, i) => b !== checksum[i])) {
|
|
99
|
+
throw new Error("Invalid legacy address checksum");
|
|
100
|
+
}
|
|
101
|
+
const hashbytes = decoded.slice(1, 21);
|
|
102
|
+
let version;
|
|
103
|
+
if (versionByte === 0 || versionByte === 111) {
|
|
104
|
+
version = POX_ADDRESS_VERSION.p2pkh;
|
|
105
|
+
} else if (versionByte === 5 || versionByte === 196) {
|
|
106
|
+
version = POX_ADDRESS_VERSION.p2sh;
|
|
107
|
+
} else {
|
|
108
|
+
throw new Error(`Unknown legacy address version byte: 0x${versionByte.toString(16)}`);
|
|
109
|
+
}
|
|
110
|
+
return { version, hashbytes };
|
|
111
|
+
}
|
|
112
|
+
function stringifyBtcAddress(repr, network) {
|
|
113
|
+
const { version, hashbytes } = canonicalizeBtcAddress(repr);
|
|
114
|
+
const params = BITCOIN_NETWORK_PARAMS[network];
|
|
115
|
+
switch (version) {
|
|
116
|
+
case POX_ADDRESS_VERSION.p2pkh:
|
|
117
|
+
return base58CheckEncode(params.p2pkh, hashbytes);
|
|
118
|
+
case POX_ADDRESS_VERSION.p2sh:
|
|
119
|
+
case POX_ADDRESS_VERSION.p2sh_p2wpkh:
|
|
120
|
+
case POX_ADDRESS_VERSION.p2sh_p2wsh:
|
|
121
|
+
return base58CheckEncode(params.p2sh, hashbytes);
|
|
122
|
+
case POX_ADDRESS_VERSION.p2wpkh:
|
|
123
|
+
case POX_ADDRESS_VERSION.p2wsh:
|
|
124
|
+
return bech32.encode(params.hrp, [0, ...bech32.toWords(hashbytes)]);
|
|
125
|
+
case POX_ADDRESS_VERSION.p2tr:
|
|
126
|
+
return bech32m.encode(params.hrp, [1, ...bech32m.toWords(hashbytes)]);
|
|
127
|
+
default:
|
|
128
|
+
throw new Error(`Unknown PoX address version: 0x${version.toString(16)}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
var BtcAddress = {
|
|
132
|
+
parse: parseBtcAddress,
|
|
133
|
+
stringify: stringifyBtcAddress
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export { POX_CONTRACTS, MIN_LOCK_PERIOD, MAX_LOCK_PERIOD, POX_ADDRESS_VERSION, canonicalizeBtcAddress, parseBtcAddress, stringifyBtcAddress, BtcAddress };
|
|
137
|
+
|
|
138
|
+
//# debugId=1E88CAA6C41700FD64756E2164756E21
|
|
139
|
+
//# sourceMappingURL=stacks-yajyej2y.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/pox/constants.ts", "../src/pox5/btcAddress.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"export const POX_CONTRACTS = {\n\tmainnet: {\n\t\taddress: \"SP000000000000000000002Q6VF78\",\n\t\tname: \"pox-4\",\n\t},\n\ttestnet: {\n\t\taddress: \"ST000000000000000000002AMW42H\",\n\t\tname: \"pox-4\",\n\t},\n} as const;\n\nexport const MIN_LOCK_PERIOD = 1;\nexport const MAX_LOCK_PERIOD = 12;\n\n/** PoX address version bytes (maps to Bitcoin address types) */\nexport const POX_ADDRESS_VERSION = {\n\t/** P2PKH - legacy addresses starting with \"1\" */\n\tp2pkh: 0x00,\n\t/** P2SH - script hash addresses starting with \"3\" */\n\tp2sh: 0x01,\n\t/** P2SH-P2WPKH - nested segwit */\n\tp2sh_p2wpkh: 0x02,\n\t/** P2SH-P2WSH - nested segwit script */\n\tp2sh_p2wsh: 0x03,\n\t/** P2WPKH - native segwit \"bc1q\" (20-byte hash) */\n\tp2wpkh: 0x04,\n\t/** P2WSH - native segwit \"bc1q\" (32-byte hash) */\n\tp2wsh: 0x05,\n\t/** P2TR - taproot \"bc1p\" (32-byte key) */\n\tp2tr: 0x06,\n} as const;\n",
|
|
6
|
+
"import { base58, bech32, bech32m } from \"@scure/base\";\nimport {\n\tBITCOIN_NETWORK_PARAMS,\n\tbase58CheckEncode,\n} from \"../bitcoin/address.ts\";\nimport type { BitcoinNetwork } from \"../bitcoin/constants.ts\";\nimport { doubleSha256 } from \"../bitcoin/serialize.ts\";\nimport { POX_ADDRESS_VERSION } from \"../pox/constants.ts\";\n\n/**\n * SIP-005 PoX `pox-addr` tuple, decoded from a Bitcoin address. `version` is\n * the PoX byte (`POX_ADDRESS_VERSION`), not a Bitcoin network version\n * (`p2sh` is 0x01 here, 0x05 on mainnet Bitcoin). `hashbytes` is the 20- or\n * 32-byte payload — unpadded, matching `check-pox-addr-hashbytes`.\n */\nexport type BtcAddressRepr = {\n\tversion: number;\n\thashbytes: Uint8Array;\n};\n\nfunction expectedHashLen(version: number): number {\n\tif (!Number.isInteger(version) || version < 0x00 || version > 0x06) {\n\t\tthrow new Error(`Unknown PoX address version: 0x${version.toString(16)}`);\n\t}\n\treturn version <= 0x04 ? 20 : 32;\n}\n\n/** Strip frozen-pox 32-byte padding; reject a length that doesn't match the version. */\nexport function canonicalizeBtcAddress(repr: BtcAddressRepr): BtcAddressRepr {\n\tconst expected = expectedHashLen(repr.version);\n\tconst { hashbytes } = repr;\n\tif (hashbytes.length === expected)\n\t\treturn { version: repr.version, hashbytes };\n\tif (\n\t\texpected === 20 &&\n\t\thashbytes.length === 32 &&\n\t\thashbytes.slice(20).every((b) => b === 0)\n\t) {\n\t\treturn { version: repr.version, hashbytes: hashbytes.slice(0, 20) };\n\t}\n\tthrow new Error(\n\t\t`Invalid hashbytes length for PoX version 0x${repr.version.toString(16)}: ${hashbytes.length}`,\n\t);\n}\n\n/**\n * Parse a Bitcoin address string into a PoX address tuple.\n * Supports P2PKH, P2SH, P2WPKH, P2WSH, P2TR (mainnet, testnet, regtest).\n */\nexport function parseBtcAddress(address: string): BtcAddressRepr {\n\tif (\n\t\taddress.startsWith(\"bc1\") ||\n\t\taddress.startsWith(\"tb1\") ||\n\t\taddress.startsWith(\"bcrt1\")\n\t) {\n\t\treturn parseSegwitAddress(address);\n\t}\n\treturn parseLegacyAddress(address);\n}\n\nfunction parseSegwitAddress(address: string): BtcAddressRepr {\n\tlet decoded: { prefix: string; words: number[] };\n\ttry {\n\t\tdecoded = bech32.decode(address as `${string}1${string}`);\n\t} catch {\n\t\tdecoded = bech32m.decode(address as `${string}1${string}`);\n\t}\n\n\tconst witnessVersion = decoded.words[0];\n\tif (witnessVersion === undefined) {\n\t\tthrow new Error(\"Invalid segwit address: missing witness version\");\n\t}\n\tconst data = bech32.fromWords(decoded.words.slice(1));\n\tconst hashbytes = new Uint8Array(data);\n\n\tlet version: number;\n\tif (witnessVersion === 0) {\n\t\tif (hashbytes.length === 20) {\n\t\t\tversion = POX_ADDRESS_VERSION.p2wpkh;\n\t\t} else if (hashbytes.length === 32) {\n\t\t\tversion = POX_ADDRESS_VERSION.p2wsh;\n\t\t} else {\n\t\t\tthrow new Error(`Invalid witness v0 program length: ${hashbytes.length}`);\n\t\t}\n\t} else if (witnessVersion === 1) {\n\t\tif (hashbytes.length !== 32) {\n\t\t\tthrow new Error(`Invalid witness v1 program length: ${hashbytes.length}`);\n\t\t}\n\t\tversion = POX_ADDRESS_VERSION.p2tr;\n\t} else {\n\t\tthrow new Error(`Unsupported witness version: ${witnessVersion}`);\n\t}\n\n\treturn { version, hashbytes };\n}\n\nfunction parseLegacyAddress(address: string): BtcAddressRepr {\n\tconst decoded = base58.decode(address);\n\n\tif (decoded.length !== 25) {\n\t\tthrow new Error(`Invalid legacy address length: ${decoded.length}`);\n\t}\n\n\tconst versionByte = decoded[0];\n\tif (versionByte === undefined) {\n\t\tthrow new Error(\"Invalid legacy address: missing version byte\");\n\t}\n\tconst payload = decoded.slice(0, 21);\n\tconst checksum = decoded.slice(21);\n\tconst expected = doubleSha256(payload).slice(0, 4);\n\tif (checksum.length !== 4 || expected.some((b, i) => b !== checksum[i])) {\n\t\tthrow new Error(\"Invalid legacy address checksum\");\n\t}\n\tconst hashbytes = decoded.slice(1, 21);\n\n\tlet version: number;\n\tif (versionByte === 0x00 || versionByte === 0x6f) {\n\t\tversion = POX_ADDRESS_VERSION.p2pkh;\n\t} else if (versionByte === 0x05 || versionByte === 0xc4) {\n\t\tversion = POX_ADDRESS_VERSION.p2sh;\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Unknown legacy address version byte: 0x${versionByte.toString(16)}`,\n\t\t);\n\t}\n\n\treturn { version, hashbytes };\n}\n\nexport function stringifyBtcAddress(\n\trepr: BtcAddressRepr,\n\tnetwork: BitcoinNetwork,\n): string {\n\tconst { version, hashbytes } = canonicalizeBtcAddress(repr);\n\tconst params = BITCOIN_NETWORK_PARAMS[network];\n\tswitch (version) {\n\t\tcase POX_ADDRESS_VERSION.p2pkh:\n\t\t\treturn base58CheckEncode(params.p2pkh, hashbytes);\n\t\tcase POX_ADDRESS_VERSION.p2sh:\n\t\tcase POX_ADDRESS_VERSION.p2sh_p2wpkh:\n\t\tcase POX_ADDRESS_VERSION.p2sh_p2wsh:\n\t\t\treturn base58CheckEncode(params.p2sh, hashbytes);\n\t\tcase POX_ADDRESS_VERSION.p2wpkh:\n\t\tcase POX_ADDRESS_VERSION.p2wsh:\n\t\t\treturn bech32.encode(params.hrp, [0, ...bech32.toWords(hashbytes)]);\n\t\tcase POX_ADDRESS_VERSION.p2tr:\n\t\t\treturn bech32m.encode(params.hrp, [1, ...bech32m.toWords(hashbytes)]);\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown PoX address version: 0x${version.toString(16)}`);\n\t}\n}\n\nexport const BtcAddress: {\n\tparse: typeof parseBtcAddress;\n\tstringify: typeof stringifyBtcAddress;\n} = {\n\tparse: parseBtcAddress,\n\tstringify: stringifyBtcAddress,\n};\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": ";;;;;;;AAAO,IAAM,gBAAgB;AAAA,EAC5B,SAAS;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,EACP;AAAA,EACA,SAAS;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,EACP;AACD;AAEO,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAGxB,IAAM,sBAAsB;AAAA,EAElC,OAAO;AAAA,EAEP,MAAM;AAAA,EAEN,aAAa;AAAA,EAEb,YAAY;AAAA,EAEZ,QAAQ;AAAA,EAER,OAAO;AAAA,EAEP,MAAM;AACP;;;AC9BA;AAoBA,SAAS,eAAe,CAAC,SAAyB;AAAA,EACjD,IAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,KAAQ,UAAU,GAAM;AAAA,IACnE,MAAM,IAAI,MAAM,kCAAkC,QAAQ,SAAS,EAAE,GAAG;AAAA,EACzE;AAAA,EACA,OAAO,WAAW,IAAO,KAAK;AAAA;AAIxB,SAAS,sBAAsB,CAAC,MAAsC;AAAA,EAC5E,MAAM,WAAW,gBAAgB,KAAK,OAAO;AAAA,EAC7C,QAAQ,cAAc;AAAA,EACtB,IAAI,UAAU,WAAW;AAAA,IACxB,OAAO,EAAE,SAAS,KAAK,SAAS,UAAU;AAAA,EAC3C,IACC,aAAa,MACb,UAAU,WAAW,MACrB,UAAU,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,MAAM,CAAC,GACvC;AAAA,IACD,OAAO,EAAE,SAAS,KAAK,SAAS,WAAW,UAAU,MAAM,GAAG,EAAE,EAAE;AAAA,EACnE;AAAA,EACA,MAAM,IAAI,MACT,8CAA8C,KAAK,QAAQ,SAAS,EAAE,MAAM,UAAU,QACvF;AAAA;AAOM,SAAS,eAAe,CAAC,SAAiC;AAAA,EAChE,IACC,QAAQ,WAAW,KAAK,KACxB,QAAQ,WAAW,KAAK,KACxB,QAAQ,WAAW,OAAO,GACzB;AAAA,IACD,OAAO,mBAAmB,OAAO;AAAA,EAClC;AAAA,EACA,OAAO,mBAAmB,OAAO;AAAA;AAGlC,SAAS,kBAAkB,CAAC,SAAiC;AAAA,EAC5D,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,UAAU,OAAO,OAAO,OAAgC;AAAA,IACvD,MAAM;AAAA,IACP,UAAU,QAAQ,OAAO,OAAgC;AAAA;AAAA,EAG1D,MAAM,iBAAiB,QAAQ,MAAM;AAAA,EACrC,IAAI,mBAAmB,WAAW;AAAA,IACjC,MAAM,IAAI,MAAM,iDAAiD;AAAA,EAClE;AAAA,EACA,MAAM,OAAO,OAAO,UAAU,QAAQ,MAAM,MAAM,CAAC,CAAC;AAAA,EACpD,MAAM,YAAY,IAAI,WAAW,IAAI;AAAA,EAErC,IAAI;AAAA,EACJ,IAAI,mBAAmB,GAAG;AAAA,IACzB,IAAI,UAAU,WAAW,IAAI;AAAA,MAC5B,UAAU,oBAAoB;AAAA,IAC/B,EAAO,SAAI,UAAU,WAAW,IAAI;AAAA,MACnC,UAAU,oBAAoB;AAAA,IAC/B,EAAO;AAAA,MACN,MAAM,IAAI,MAAM,sCAAsC,UAAU,QAAQ;AAAA;AAAA,EAE1E,EAAO,SAAI,mBAAmB,GAAG;AAAA,IAChC,IAAI,UAAU,WAAW,IAAI;AAAA,MAC5B,MAAM,IAAI,MAAM,sCAAsC,UAAU,QAAQ;AAAA,IACzE;AAAA,IACA,UAAU,oBAAoB;AAAA,EAC/B,EAAO;AAAA,IACN,MAAM,IAAI,MAAM,gCAAgC,gBAAgB;AAAA;AAAA,EAGjE,OAAO,EAAE,SAAS,UAAU;AAAA;AAG7B,SAAS,kBAAkB,CAAC,SAAiC;AAAA,EAC5D,MAAM,UAAU,OAAO,OAAO,OAAO;AAAA,EAErC,IAAI,QAAQ,WAAW,IAAI;AAAA,IAC1B,MAAM,IAAI,MAAM,kCAAkC,QAAQ,QAAQ;AAAA,EACnE;AAAA,EAEA,MAAM,cAAc,QAAQ;AAAA,EAC5B,IAAI,gBAAgB,WAAW;AAAA,IAC9B,MAAM,IAAI,MAAM,8CAA8C;AAAA,EAC/D;AAAA,EACA,MAAM,UAAU,QAAQ,MAAM,GAAG,EAAE;AAAA,EACnC,MAAM,WAAW,QAAQ,MAAM,EAAE;AAAA,EACjC,MAAM,WAAW,aAAa,OAAO,EAAE,MAAM,GAAG,CAAC;AAAA,EACjD,IAAI,SAAS,WAAW,KAAK,SAAS,KAAK,CAAC,GAAG,MAAM,MAAM,SAAS,EAAE,GAAG;AAAA,IACxE,MAAM,IAAI,MAAM,iCAAiC;AAAA,EAClD;AAAA,EACA,MAAM,YAAY,QAAQ,MAAM,GAAG,EAAE;AAAA,EAErC,IAAI;AAAA,EACJ,IAAI,gBAAgB,KAAQ,gBAAgB,KAAM;AAAA,IACjD,UAAU,oBAAoB;AAAA,EAC/B,EAAO,SAAI,gBAAgB,KAAQ,gBAAgB,KAAM;AAAA,IACxD,UAAU,oBAAoB;AAAA,EAC/B,EAAO;AAAA,IACN,MAAM,IAAI,MACT,0CAA0C,YAAY,SAAS,EAAE,GAClE;AAAA;AAAA,EAGD,OAAO,EAAE,SAAS,UAAU;AAAA;AAGtB,SAAS,mBAAmB,CAClC,MACA,SACS;AAAA,EACT,QAAQ,SAAS,cAAc,uBAAuB,IAAI;AAAA,EAC1D,MAAM,SAAS,uBAAuB;AAAA,EACtC,QAAQ;AAAA,SACF,oBAAoB;AAAA,MACxB,OAAO,kBAAkB,OAAO,OAAO,SAAS;AAAA,SAC5C,oBAAoB;AAAA,SACpB,oBAAoB;AAAA,SACpB,oBAAoB;AAAA,MACxB,OAAO,kBAAkB,OAAO,MAAM,SAAS;AAAA,SAC3C,oBAAoB;AAAA,SACpB,oBAAoB;AAAA,MACxB,OAAO,OAAO,OAAO,OAAO,KAAK,CAAC,GAAG,GAAG,OAAO,QAAQ,SAAS,CAAC,CAAC;AAAA,SAC9D,oBAAoB;AAAA,MACxB,OAAO,QAAQ,OAAO,OAAO,KAAK,CAAC,GAAG,GAAG,QAAQ,QAAQ,SAAS,CAAC,CAAC;AAAA;AAAA,MAEpE,MAAM,IAAI,MAAM,kCAAkC,QAAQ,SAAS,EAAE,GAAG;AAAA;AAAA;AAIpE,IAAM,aAGT;AAAA,EACH,OAAO;AAAA,EACP,WAAW;AACZ;",
|
|
9
|
+
"debugId": "1E88CAA6C41700FD64756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -11,8 +11,18 @@ function formatUnits(value, decimals) {
|
|
|
11
11
|
const result = `${integer}.${fraction}`;
|
|
12
12
|
return negative ? `-${result}` : result;
|
|
13
13
|
}
|
|
14
|
+
var DECIMAL_STRING = /^-?\d+(\.\d+)?$/;
|
|
14
15
|
function parseUnits(value, decimals) {
|
|
15
|
-
|
|
16
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
17
|
+
throw new RangeError(`Cannot parse ${value} as a decimal amount`);
|
|
18
|
+
}
|
|
19
|
+
let str = typeof value === "number" ? value.toFixed(decimals) : value.trim();
|
|
20
|
+
if (!DECIMAL_STRING.test(str)) {
|
|
21
|
+
throw new RangeError(`Cannot parse "${value}" as a decimal amount: expected digits with an optional fraction, like "1.5"`);
|
|
22
|
+
}
|
|
23
|
+
if (typeof value === "number" && Number(str) !== value) {
|
|
24
|
+
throw new RangeError(`Cannot parse ${value} with ${decimals} decimals: pass the amount as a string to keep every digit`);
|
|
25
|
+
}
|
|
16
26
|
const negative = str.startsWith("-");
|
|
17
27
|
if (negative)
|
|
18
28
|
str = str.slice(1);
|
|
@@ -33,5 +43,5 @@ function parseStx(stx) {
|
|
|
33
43
|
|
|
34
44
|
export { formatUnits, parseUnits, formatStx, parseStx };
|
|
35
45
|
|
|
36
|
-
//# debugId=
|
|
37
|
-
//# sourceMappingURL=stacks-
|
|
46
|
+
//# debugId=8725D981B914256B64756E2164756E21
|
|
47
|
+
//# sourceMappingURL=stacks-yvb7rvwk.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/utils/units.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Format a bigint value with decimal places.\n * @example formatUnits(1000000n, 6) → \"1.0\"\n * @example formatUnits(1500000n, 6) → \"1.5\"\n */\nexport function formatUnits(\n\tvalue: bigint | number | string,\n\tdecimals: number,\n): string {\n\tlet v = BigInt(value);\n\n\tconst negative = v < 0n;\n\tif (negative) v = -v;\n\n\tconst divisor = 10n ** BigInt(decimals);\n\tconst integer = (v / divisor).toString();\n\tlet fraction = (v % divisor).toString().padStart(decimals, \"0\");\n\n\t// Trim trailing zeros, but keep at least one decimal\n\tfraction = fraction.replace(/0+$/, \"\") || \"0\";\n\n\tconst result = `${integer}.${fraction}`;\n\treturn negative ? `-${result}` : result;\n}\n\n/**\n * Parse a decimal string into a bigint with the given number of decimals.\n * @example parseUnits(\"1.5\", 6) → 1500000n\n * @example parseUnits(\"1\", 6) → 1000000n\n */\nconst DECIMAL_STRING = /^-?\\d+(\\.\\d+)?$/;\n\nexport function parseUnits(value: string | number, decimals: number): bigint {\n\tif (typeof value === \"number\" && !Number.isFinite(value)) {\n\t\tthrow new RangeError(`Cannot parse ${value} as a decimal amount`);\n\t}\n\t// Numbers small or large enough to print in exponent form (1e-7, 1e21)\n\t// go through toFixed so the digits survive. A number the fixed form\n\t// cannot hold exactly (too many decimals, or too small for one unit) is\n\t// refused rather than rounded, so amounts never shrink silently.\n\tlet str = typeof value === \"number\" ? value.toFixed(decimals) : value.trim();\n\tif (!DECIMAL_STRING.test(str)) {\n\t\tthrow new RangeError(\n\t\t\t`Cannot parse \"${value}\" as a decimal amount: expected digits with an optional fraction, like \"1.5\"`,\n\t\t);\n\t}\n\tif (typeof value === \"number\" && Number(str) !== value) {\n\t\tthrow new RangeError(\n\t\t\t`Cannot parse ${value} with ${decimals} decimals: pass the amount as a string to keep every digit`,\n\t\t);\n\t}\n\n\tconst negative = str.startsWith(\"-\");\n\tif (negative) str = str.slice(1);\n\n\tconst [integer = \"\", fraction = \"\"] = str.split(\".\");\n\n\tif (fraction.length > decimals) {\n\t\tthrow new Error(\n\t\t\t`Too many decimal places: \"${value}\" has ${fraction.length} decimals, max is ${decimals}`,\n\t\t);\n\t}\n\n\tconst padded = fraction.padEnd(decimals, \"0\");\n\tconst result = BigInt(integer + padded);\n\treturn negative ? -result : result;\n}\n\n/**\n * Format microSTX to STX string (6 decimals).\n * @example formatStx(1000000n) → \"1.0\"\n */\nexport function formatStx(microStx: bigint | number | string): string {\n\treturn formatUnits(microStx, 6);\n}\n\n/**\n * Parse STX string to microSTX bigint (6 decimals).\n * @example parseStx(\"1.5\") → 1500000n\n */\nexport function parseStx(stx: string | number): bigint {\n\treturn parseUnits(stx, 6);\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAKO,SAAS,WAAW,CAC1B,OACA,UACS;AAAA,EACT,IAAI,IAAI,OAAO,KAAK;AAAA,EAEpB,MAAM,WAAW,IAAI;AAAA,EACrB,IAAI;AAAA,IAAU,IAAI,CAAC;AAAA,EAEnB,MAAM,UAAU,OAAO,OAAO,QAAQ;AAAA,EACtC,MAAM,WAAW,IAAI,SAAS,SAAS;AAAA,EACvC,IAAI,YAAY,IAAI,SAAS,SAAS,EAAE,SAAS,UAAU,GAAG;AAAA,EAG9D,WAAW,SAAS,QAAQ,OAAO,EAAE,KAAK;AAAA,EAE1C,MAAM,SAAS,GAAG,WAAW;AAAA,EAC7B,OAAO,WAAW,IAAI,WAAW;AAAA;AAQlC,IAAM,iBAAiB;AAEhB,SAAS,UAAU,CAAC,OAAwB,UAA0B;AAAA,EAC5E,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AAAA,IACzD,MAAM,IAAI,WAAW,gBAAgB,2BAA2B;AAAA,EACjE;AAAA,EAKA,IAAI,MAAM,OAAO,UAAU,WAAW,MAAM,QAAQ,QAAQ,IAAI,MAAM,KAAK;AAAA,EAC3E,IAAI,CAAC,eAAe,KAAK,GAAG,GAAG;AAAA,IAC9B,MAAM,IAAI,WACT,iBAAiB,mFAClB;AAAA,EACD;AAAA,EACA,IAAI,OAAO,UAAU,YAAY,OAAO,GAAG,MAAM,OAAO;AAAA,IACvD,MAAM,IAAI,WACT,gBAAgB,cAAc,oEAC/B;AAAA,EACD;AAAA,EAEA,MAAM,WAAW,IAAI,WAAW,GAAG;AAAA,EACnC,IAAI;AAAA,IAAU,MAAM,IAAI,MAAM,CAAC;AAAA,EAE/B,OAAO,UAAU,IAAI,WAAW,MAAM,IAAI,MAAM,GAAG;AAAA,EAEnD,IAAI,SAAS,SAAS,UAAU;AAAA,IAC/B,MAAM,IAAI,MACT,6BAA6B,cAAc,SAAS,2BAA2B,UAChF;AAAA,EACD;AAAA,EAEA,MAAM,SAAS,SAAS,OAAO,UAAU,GAAG;AAAA,EAC5C,MAAM,SAAS,OAAO,UAAU,MAAM;AAAA,EACtC,OAAO,WAAW,CAAC,SAAS;AAAA;AAOtB,SAAS,SAAS,CAAC,UAA4C;AAAA,EACrE,OAAO,YAAY,UAAU,CAAC;AAAA;AAOxB,SAAS,QAAQ,CAAC,KAA8B;AAAA,EACtD,OAAO,WAAW,KAAK,CAAC;AAAA;",
|
|
8
|
+
"debugId": "8725D981B914256B64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
base58,
|
|
3
|
-
bech32,
|
|
4
|
-
bech32m
|
|
5
|
-
} from "./stacks-5nmz5ad9.js";
|
|
6
1
|
import {
|
|
7
2
|
concatBytes,
|
|
8
3
|
hash160,
|
|
@@ -158,13 +153,14 @@ function blockHash(header, { display = false } = {}) {
|
|
|
158
153
|
|
|
159
154
|
// src/bitcoin/address.ts
|
|
160
155
|
import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
|
|
156
|
+
import { base58, bech32, bech32m } from "@scure/base";
|
|
161
157
|
var BITCOIN_NETWORK_PARAMS = {
|
|
162
158
|
mainnet: { p2pkh: 0, p2sh: 5, hrp: "bc" },
|
|
163
159
|
testnet: { p2pkh: 111, p2sh: 196, hrp: "tb" },
|
|
164
160
|
regtest: { p2pkh: 111, p2sh: 196, hrp: "bcrt" }
|
|
165
161
|
};
|
|
166
162
|
var NETWORK_PARAMS = BITCOIN_NETWORK_PARAMS;
|
|
167
|
-
function
|
|
163
|
+
function base58CheckEncode(version, payload) {
|
|
168
164
|
const data = concatBytes(Uint8Array.of(version), payload);
|
|
169
165
|
const checksum = doubleSha256(data).slice(0, 4);
|
|
170
166
|
return base58.encode(concatBytes(data, checksum));
|
|
@@ -176,9 +172,9 @@ function formatBitcoinAddress(parsed, network = "mainnet") {
|
|
|
176
172
|
return;
|
|
177
173
|
switch (parsed.type) {
|
|
178
174
|
case "p2pkh":
|
|
179
|
-
return
|
|
175
|
+
return base58CheckEncode(params.p2pkh, hash);
|
|
180
176
|
case "p2sh":
|
|
181
|
-
return
|
|
177
|
+
return base58CheckEncode(params.p2sh, hash);
|
|
182
178
|
case "p2wpkh":
|
|
183
179
|
case "p2wsh":
|
|
184
180
|
return bech32.encode(params.hrp, [0, ...bech32.toWords(hash)]);
|
|
@@ -219,7 +215,7 @@ function publicKeyToP2trAddress(publicKey, network = "mainnet") {
|
|
|
219
215
|
return bech32m.encode(params.hrp, [1, ...bech32m.toWords(outputKey)]);
|
|
220
216
|
}
|
|
221
217
|
|
|
222
|
-
export { doubleSha256, reverseBytes, BtcReader, parseBitcoinTx, stripWitness, bitcoinTxid, parseBlockHeader, blockHash, BITCOIN_NETWORK_PARAMS, formatBitcoinAddress, taprootTweakPubkey, publicKeyToP2wpkhAddress, publicKeyToP2trAddress };
|
|
218
|
+
export { doubleSha256, reverseBytes, BtcReader, parseBitcoinTx, stripWitness, bitcoinTxid, parseBlockHeader, blockHash, BITCOIN_NETWORK_PARAMS, base58CheckEncode, formatBitcoinAddress, taprootTweakPubkey, publicKeyToP2wpkhAddress, publicKeyToP2trAddress };
|
|
223
219
|
|
|
224
|
-
//# debugId=
|
|
225
|
-
//# sourceMappingURL=stacks-
|
|
220
|
+
//# debugId=47BC2E0DF09E5D3E64756E2164756E21
|
|
221
|
+
//# sourceMappingURL=stacks-z90xdr1x.js.map
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"sources": ["../src/bitcoin/serialize.ts", "../src/bitcoin/address.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { concatBytes } from \"../utils/encoding.ts\";\nimport { sha256 } from \"../utils/hash.ts\";\n\n/**\n * Bitcoin double-SHA256: `sha256(sha256(bytes))`. This is the hash Bitcoin uses\n * for txids, block headers, and merkle nodes — NOT the same as the Stacks\n * `txidFromBytes` (which uses sha512_256), so it lives here, not in `utils/hash`.\n */\nexport function doubleSha256(bytes: Uint8Array): Uint8Array {\n\treturn sha256(sha256(bytes));\n}\n\n/**\n * Reverse a byte array. Bitcoin hashes are computed and stored in *internal*\n * (little-endian) order but *displayed* big-endian, so the two differ by a\n * reversal. The SIP-044 built-ins consume internal order; only reverse for\n * display / when matching an explorer value.\n */\nexport function reverseBytes(bytes: Uint8Array): Uint8Array {\n\tconst out = new Uint8Array(bytes.length);\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tout[i] = bytes[bytes.length - 1 - i] as number;\n\t}\n\treturn out;\n}\n\n/**\n * A little-endian, varint-aware byte reader for Bitcoin serialization. The\n * shared `utils/BytesReader` is big-endian only; Bitcoin tx fields are\n * little-endian with compact-size (varint) length prefixes.\n */\nexport class BtcReader {\n\tprivate readonly data: Uint8Array;\n\tprivate readonly view: DataView;\n\tpublic offset = 0;\n\n\tconstructor(data: Uint8Array) {\n\t\tthis.data = data;\n\t\tthis.view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\t}\n\n\tget length(): number {\n\t\treturn this.data.length;\n\t}\n\n\treadUInt8(): number {\n\t\tconst v = this.view.getUint8(this.offset);\n\t\tthis.offset += 1;\n\t\treturn v;\n\t}\n\n\t/** Read the next byte without advancing. */\n\tpeekUInt8(): number {\n\t\treturn this.view.getUint8(this.offset);\n\t}\n\n\treadUInt32LE(): number {\n\t\tconst v = this.view.getUint32(this.offset, true);\n\t\tthis.offset += 4;\n\t\treturn v;\n\t}\n\n\treadUInt64LE(): bigint {\n\t\tconst v = this.view.getBigUint64(this.offset, true);\n\t\tthis.offset += 8;\n\t\treturn v;\n\t}\n\n\treadBytes(n: number): Uint8Array {\n\t\tif (this.offset + n > this.data.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`Bitcoin tx underflow: need ${n} bytes at offset ${this.offset}, have ${this.data.length}`,\n\t\t\t);\n\t\t}\n\t\tconst slice = this.data.slice(this.offset, this.offset + n);\n\t\tthis.offset += n;\n\t\treturn slice;\n\t}\n\n\t/** Read a Bitcoin compact-size unsigned integer (varint). */\n\treadVarInt(): number {\n\t\tconst first = this.readUInt8();\n\t\tif (first < 0xfd) return first;\n\t\tif (first === 0xfd) {\n\t\t\tconst v = this.view.getUint16(this.offset, true);\n\t\t\tthis.offset += 2;\n\t\t\treturn v;\n\t\t}\n\t\tif (first === 0xfe) {\n\t\t\treturn this.readUInt32LE();\n\t\t}\n\t\tconst big = this.readUInt64LE();\n\t\tif (big > BigInt(Number.MAX_SAFE_INTEGER)) {\n\t\t\tthrow new Error(\"Bitcoin varint exceeds safe integer range\");\n\t\t}\n\t\treturn Number(big);\n\t}\n}\n\nexport interface BitcoinTxInput {\n\t/** Previous output txid, in serialized (internal) byte order. */\n\tprevTxid: Uint8Array;\n\tvout: number;\n\tscriptSig: Uint8Array;\n\tsequence: number;\n}\n\nexport interface BitcoinTxOutput {\n\t/** Output value in satoshis. */\n\tvalue: bigint;\n\tscriptPubKey: Uint8Array;\n}\n\nexport interface ParsedBitcoinTx {\n\tversion: number;\n\thasWitness: boolean;\n\tinputs: BitcoinTxInput[];\n\toutputs: BitcoinTxOutput[];\n\tlocktime: number;\n\t/**\n\t * The legacy txid as the raw double-SHA256 in *internal* byte order — ready\n\t * to pass as the leaf to `verify-merkle-proof`. Witness data is excluded\n\t * (the txid is computed over the legacy serialization), so this is stable for\n\t * both legacy and SegWit txs. Use `reverseBytes` for the displayed form.\n\t */\n\ttxidInternal: Uint8Array;\n}\n\ninterface ScanResult {\n\tversion: number;\n\thasWitness: boolean;\n\tinputs: BitcoinTxInput[];\n\toutputs: BitcoinTxOutput[];\n\tlocktime: number;\n\t/** The legacy (witness-stripped) serialization — what the txid is hashed over. */\n\tlegacy: Uint8Array;\n}\n\n/**\n * Single-pass scan of a raw Bitcoin tx. Captures the inputs/outputs slice and\n * reassembles the legacy serialization so both `parseBitcoinTx` and\n * `stripWitness` share one parser (and one set of foot-guns).\n */\nfunction scanTx(rawTx: Uint8Array): ScanResult {\n\tconst r = new BtcReader(rawTx);\n\tconst version = r.readUInt32LE();\n\n\t// SegWit marker (0x00) + flag (0x01) sit immediately after the version. A\n\t// legacy tx can never have a zero input count, so 0x00 here is unambiguous.\n\tlet hasWitness = false;\n\tif (r.peekUInt8() === 0x00) {\n\t\tr.readUInt8(); // marker\n\t\tconst flag = r.readUInt8();\n\t\tif (flag !== 0x01) {\n\t\t\tthrow new Error(`Unexpected SegWit flag 0x${flag.toString(16)}`);\n\t\t}\n\t\thasWitness = true;\n\t}\n\n\tconst bodyStart = r.offset;\n\tconst inputCount = r.readVarInt();\n\tconst inputs: BitcoinTxInput[] = [];\n\tfor (let i = 0; i < inputCount; i++) {\n\t\tconst prevTxid = r.readBytes(32);\n\t\tconst vout = r.readUInt32LE();\n\t\tconst scriptSig = r.readBytes(r.readVarInt());\n\t\tconst sequence = r.readUInt32LE();\n\t\tinputs.push({ prevTxid, vout, scriptSig, sequence });\n\t}\n\n\tconst outputCount = r.readVarInt();\n\tconst outputs: BitcoinTxOutput[] = [];\n\tfor (let i = 0; i < outputCount; i++) {\n\t\tconst value = r.readUInt64LE();\n\t\tconst scriptPubKey = r.readBytes(r.readVarInt());\n\t\toutputs.push({ value, scriptPubKey });\n\t}\n\tconst bodyEnd = r.offset;\n\n\tif (hasWitness) {\n\t\tfor (let i = 0; i < inputCount; i++) {\n\t\t\tconst itemCount = r.readVarInt();\n\t\t\tfor (let j = 0; j < itemCount; j++) {\n\t\t\t\tr.readBytes(r.readVarInt());\n\t\t\t}\n\t\t}\n\t}\n\n\tconst locktime = r.readUInt32LE();\n\n\tconst legacy = concatBytes(\n\t\trawTx.slice(0, 4),\n\t\trawTx.slice(bodyStart, bodyEnd),\n\t\trawTx.slice(r.offset - 4, r.offset),\n\t);\n\n\treturn { version, hasWitness, inputs, outputs, locktime, legacy };\n}\n\n/** Parse a serialized Bitcoin tx (legacy or SegWit) into its fields + txid. */\nexport function parseBitcoinTx(rawTx: Uint8Array): ParsedBitcoinTx {\n\tconst s = scanTx(rawTx);\n\treturn {\n\t\tversion: s.version,\n\t\thasWitness: s.hasWitness,\n\t\tinputs: s.inputs,\n\t\toutputs: s.outputs,\n\t\tlocktime: s.locktime,\n\t\ttxidInternal: doubleSha256(s.legacy),\n\t};\n}\n\n/**\n * Return the legacy (witness-stripped) serialization of a tx. For a legacy tx\n * this is the input unchanged; for a SegWit tx the marker, flag, and witness\n * stack are removed. This is the byte string the txid is hashed over.\n */\nexport function stripWitness(rawTx: Uint8Array): Uint8Array {\n\treturn scanTx(rawTx).legacy;\n}\n\n/**\n * Compute a tx's id from its raw serialization. Internal byte order by default\n * (the merkle leaf / built-in input); pass `{ display: true }` for the\n * explorer-style big-endian form.\n */\nexport function bitcoinTxid(\n\trawTx: Uint8Array,\n\t{ display = false }: { display?: boolean } = {},\n): Uint8Array {\n\tconst txid = doubleSha256(scanTx(rawTx).legacy);\n\treturn display ? reverseBytes(txid) : txid;\n}\n\nexport interface BlockHeader {\n\tversion: number;\n\t/** Previous block hash, internal byte order. */\n\tprevBlock: Uint8Array;\n\t/** Merkle root, internal byte order — pairs with `verify-merkle-proof`. */\n\tmerkleRoot: Uint8Array;\n\ttimestamp: number;\n\tbits: number;\n\tnonce: number;\n}\n\n/** Parse an 80-byte Bitcoin block header into its fields (hashes internal order). */\nexport function parseBlockHeader(header: Uint8Array): BlockHeader {\n\tif (header.length !== 80) {\n\t\tthrow new Error(\n\t\t\t`Bitcoin block header must be 80 bytes, got ${header.length}`,\n\t\t);\n\t}\n\tconst r = new BtcReader(header);\n\tconst version = r.readUInt32LE();\n\tconst prevBlock = r.readBytes(32);\n\tconst merkleRoot = r.readBytes(32);\n\tconst timestamp = r.readUInt32LE();\n\tconst bits = r.readUInt32LE();\n\tconst nonce = r.readUInt32LE();\n\treturn { version, prevBlock, merkleRoot, timestamp, bits, nonce };\n}\n\n/**\n * Hash an 80-byte block header (double-SHA256). Internal byte order by default;\n * `{ display: true }` for the explorer-style block hash.\n */\nexport function blockHash(\n\theader: Uint8Array,\n\t{ display = false }: { display?: boolean } = {},\n): Uint8Array {\n\tconst hash = doubleSha256(header);\n\treturn display ? reverseBytes(hash) : hash;\n}\n",
|
|
6
|
-
"import { schnorr, secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { base58, bech32, bech32m } from \"@scure/base\";\nimport { concatBytes, hexToBytes } from \"../utils/encoding.ts\";\nimport { hash160 } from \"../utils/hash.ts\";\nimport type { ParsedOutputScript } from \"./codec.ts\";\nimport type { BitcoinNetwork } from \"./constants.ts\";\nimport { doubleSha256 } from \"./serialize.ts\";\n\n/** Address-encoding parameters (base58 version bytes + bech32 hrp) per network. */\nexport const BITCOIN_NETWORK_PARAMS = {\n\tmainnet: { p2pkh: 0x00, p2sh: 0x05, hrp: \"bc\" },\n\ttestnet: { p2pkh: 0x6f, p2sh: 0xc4, hrp: \"tb\" },\n\tregtest: { p2pkh: 0x6f, p2sh: 0xc4, hrp: \"bcrt\" },\n} as const;\n\nconst NETWORK_PARAMS = BITCOIN_NETWORK_PARAMS;\n\n/** Base58Check-encode a versioned 20-byte payload (legacy P2PKH / P2SH). */\
|
|
6
|
+
"import { schnorr, secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { base58, bech32, bech32m } from \"@scure/base\";\nimport { concatBytes, hexToBytes } from \"../utils/encoding.ts\";\nimport { hash160 } from \"../utils/hash.ts\";\nimport type { ParsedOutputScript } from \"./codec.ts\";\nimport type { BitcoinNetwork } from \"./constants.ts\";\nimport { doubleSha256 } from \"./serialize.ts\";\n\n/** Address-encoding parameters (base58 version bytes + bech32 hrp) per network. */\nexport const BITCOIN_NETWORK_PARAMS = {\n\tmainnet: { p2pkh: 0x00, p2sh: 0x05, hrp: \"bc\" },\n\ttestnet: { p2pkh: 0x6f, p2sh: 0xc4, hrp: \"tb\" },\n\tregtest: { p2pkh: 0x6f, p2sh: 0xc4, hrp: \"bcrt\" },\n} as const;\n\nconst NETWORK_PARAMS = BITCOIN_NETWORK_PARAMS;\n\n/** Base58Check-encode a versioned 20-byte payload (legacy P2PKH / P2SH).\n * The one encoder for the package; pox5 and sbtc address code import it. */\nexport function base58CheckEncode(\n\tversion: number,\n\tpayload: Uint8Array,\n): string {\n\tconst data = concatBytes(Uint8Array.of(version), payload);\n\tconst checksum = doubleSha256(data).slice(0, 4);\n\treturn base58.encode(concatBytes(data, checksum));\n}\n\n/**\n * Render a parsed output script as a Bitcoin address for the given network.\n * Returns `undefined` for scripts without a standard address (OP_RETURN, P2PK,\n * unknown). Address encoding is network-dependent, which is why this is separate\n * from the pure `parseOutputScript` decoder.\n */\nexport function formatBitcoinAddress(\n\tparsed: ParsedOutputScript,\n\tnetwork: BitcoinNetwork = \"mainnet\",\n): string | undefined {\n\tconst params = NETWORK_PARAMS[network];\n\tconst hash = parsed.hash;\n\tif (!hash) return undefined;\n\tswitch (parsed.type) {\n\t\tcase \"p2pkh\":\n\t\t\treturn base58CheckEncode(params.p2pkh, hash);\n\t\tcase \"p2sh\":\n\t\t\treturn base58CheckEncode(params.p2sh, hash);\n\t\tcase \"p2wpkh\":\n\t\tcase \"p2wsh\":\n\t\t\treturn bech32.encode(params.hrp, [0, ...bech32.toWords(hash)]);\n\t\tcase \"p2tr\":\n\t\t\treturn bech32m.encode(params.hrp, [1, ...bech32m.toWords(hash)]);\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction toPubkeyBytes(publicKey: Uint8Array | string): Uint8Array {\n\treturn typeof publicKey === \"string\" ? hexToBytes(publicKey) : publicKey;\n}\n\n/**\n * BIP341 key-path tweak: lift the x-only internal key to a point, add\n * `tapTweakHash(P)·G` (no script tree), and return the x-only output key.\n */\nexport function taprootTweakPubkey(xonly: Uint8Array): Uint8Array {\n\tif (xonly.length !== 32)\n\t\tthrow new Error(`Expected 32-byte x-only pubkey, got ${xonly.length}`);\n\tconst tweak = schnorr.utils.taggedHash(\"TapTweak\", xonly);\n\tconst t = BigInt(\n\t\t`0x${Array.from(tweak, (b) => b.toString(16).padStart(2, \"0\")).join(\"\")}`,\n\t);\n\tif (t >= secp256k1.Point.Fn.ORDER)\n\t\tthrow new Error(\"Invalid tap tweak (exceeds curve order)\");\n\tconst internal = secp256k1.Point.fromBytes(\n\t\tconcatBytes(Uint8Array.of(0x02), xonly),\n\t);\n\tconst output = internal.add(secp256k1.Point.BASE.multiply(t));\n\treturn output.toBytes(true).slice(1);\n}\n\n/**\n * Derive the native-segwit (P2WPKH, bech32 v0) address for a compressed\n * public key.\n */\nexport function publicKeyToP2wpkhAddress(\n\tpublicKey: Uint8Array | string,\n\tnetwork: BitcoinNetwork = \"mainnet\",\n): string {\n\tconst pubkey = toPubkeyBytes(publicKey);\n\tif (pubkey.length !== 33)\n\t\tthrow new Error(`Expected 33-byte compressed pubkey, got ${pubkey.length}`);\n\tconst params = NETWORK_PARAMS[network];\n\treturn bech32.encode(params.hrp, [0, ...bech32.toWords(hash160(pubkey))]);\n}\n\n/**\n * Derive the taproot (P2TR, bech32m v1) address for a public key — BIP341\n * key-path spend, no script tree. Accepts a 33-byte compressed key (the\n * parity byte is dropped) or a 32-byte x-only key.\n */\nexport function publicKeyToP2trAddress(\n\tpublicKey: Uint8Array | string,\n\tnetwork: BitcoinNetwork = \"mainnet\",\n): string {\n\tconst pubkey = toPubkeyBytes(publicKey);\n\tconst xonly =\n\t\tpubkey.length === 33\n\t\t\t? pubkey.slice(1)\n\t\t\t: pubkey.length === 32\n\t\t\t\t? pubkey\n\t\t\t\t: undefined;\n\tif (!xonly)\n\t\tthrow new Error(\n\t\t\t`Expected 33-byte compressed or 32-byte x-only pubkey, got ${pubkey.length}`,\n\t\t);\n\tconst params = NETWORK_PARAMS[network];\n\tconst outputKey = taprootTweakPubkey(xonly);\n\treturn bech32m.encode(params.hrp, [1, ...bech32m.toWords(outputKey)]);\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": "
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "47BC2E0DF09E5D3E64756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
publicKeyToP2trAddress,
|
|
3
3
|
publicKeyToP2wpkhAddress
|
|
4
|
-
} from "../../shared/stacks-
|
|
5
|
-
import"../../shared/stacks-5nmz5ad9.js";
|
|
4
|
+
} from "../../shared/stacks-z90xdr1x.js";
|
|
6
5
|
import {
|
|
7
6
|
providerToAccount
|
|
8
7
|
} from "../../shared/stacks-qcae5852.js";
|
|
@@ -126,5 +125,5 @@ export {
|
|
|
126
125
|
compressPrivateKey
|
|
127
126
|
};
|
|
128
127
|
|
|
129
|
-
//# debugId=
|
|
128
|
+
//# debugId=5F5B69B9E824EA8664756E2164756E21
|
|
130
129
|
//# sourceMappingURL=index.js.map
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"import { HDKey } from \"@scure/bip32\";\nimport { mnemonicToSeedSync } from \"@scure/bip39\";\nimport {\n\tpublicKeyToP2trAddress,\n\tpublicKeyToP2wpkhAddress,\n} from \"../bitcoin/address.ts\";\nimport type { BitcoinNetwork } from \"../bitcoin/constants.ts\";\nimport { bytesToHex } from \"../utils/encoding.ts\";\n\nexport type BitcoinKeyType = \"p2wpkh\" | \"p2tr\";\n\nexport type MnemonicToBitcoinKeysOptions = {\n\t/** `'p2wpkh'` (BIP84, `bc1q…`) or `'p2tr'` (BIP86, `bc1p…`). */\n\ttype: BitcoinKeyType;\n\tnetwork?: BitcoinNetwork;\n\taccountIndex?: number;\n\t/** 0 = receive chain, 1 = change chain. */\n\tchangeIndex?: number;\n\taddressIndex?: number;\n};\n\nexport type BitcoinKeys = {\n\t/** 32-byte private key, hex. */\n\tprivateKey: string;\n\t/** 33-byte compressed public key, hex. */\n\tpublicKey: string;\n\taddress: string;\n\t/** Full BIP84/BIP86 derivation path. */\n\tpath: string;\n};\n\nconst PURPOSE: Record<BitcoinKeyType, number> = { p2wpkh: 84, p2tr: 86 };\n\n/**\n * Derive Bitcoin keys + address from the same mnemonic that backs a Stacks\n * account — BIP84 (native segwit) or BIP86 (taproot) paths, matching what\n * Leather/Xverse derive for the paired BTC account. Pure derivation: no\n * Bitcoin transaction building or signing.\n *\n * @example\n * const btc = mnemonicToBitcoinKeys(mnemonic, { type: \"p2tr\" });\n * btc.address; // bc1p…\n * btc.path; // m/86'/0'/0'/0/0\n */\nexport function mnemonicToBitcoinKeys(\n\tmnemonic: string,\n\toptions: MnemonicToBitcoinKeysOptions,\n): BitcoinKeys {\n\tconst {\n\t\ttype,\n\t\tnetwork = \"mainnet\",\n\t\taccountIndex = 0,\n\t\tchangeIndex = 0,\n\t\taddressIndex = 0,\n\t} = options;\n\n\t// BIP44 coin type: 0' mainnet, 1' testnet/regtest.\n\tconst coinType = network === \"mainnet\" ? 0 : 1;\n\tconst path = `m/${PURPOSE[type]}'/${coinType}'/${accountIndex}'/${changeIndex}/${addressIndex}`;\n\n\tconst seed = mnemonicToSeedSync(mnemonic);\n\tconst child = HDKey.fromMasterSeed(seed).derive(path);\n\tif (!child.privateKey || !child.publicKey)\n\t\tthrow new Error(\"Failed to derive Bitcoin key\");\n\n\tconst address =\n\t\ttype === \"p2wpkh\"\n\t\t\t? publicKeyToP2wpkhAddress(child.publicKey, network)\n\t\t\t: publicKeyToP2trAddress(child.publicKey, network);\n\n\treturn {\n\t\tprivateKey: bytesToHex(child.privateKey),\n\t\tpublicKey: bytesToHex(child.publicKey),\n\t\taddress,\n\t\tpath,\n\t};\n}\n",
|
|
8
8
|
"import type { AccountSource, CustomAccount } from \"./types.ts\";\n\nexport function toAccount(source: AccountSource): CustomAccount {\n\treturn {\n\t\ttype: \"custom\",\n\t\taddress: source.address,\n\t\tpublicKey: source.publicKey,\n\t\tsign: source.sign,\n\t};\n}\n"
|
|
9
9
|
],
|
|
10
|
-
"mappings": "
|
|
11
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "5F5B69B9E824EA8664756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
|
@@ -21,6 +21,7 @@ __export(exports_actions, {
|
|
|
21
21
|
minimumFee: () => minimumFee,
|
|
22
22
|
isResponseOutput: () => isResponseOutput,
|
|
23
23
|
isProviderAccount: () => isProviderAccount,
|
|
24
|
+
isNoEstimateAvailable: () => isNoEstimateAvailable,
|
|
24
25
|
isFeeTier: () => isFeeTier,
|
|
25
26
|
indexTxSource: () => indexTxSource,
|
|
26
27
|
getTransaction: () => getTransaction,
|
|
@@ -47,5 +48,5 @@ __export(exports_actions, {
|
|
|
47
48
|
});
|
|
48
49
|
module.exports = __toCommonJS(exports_actions);
|
|
49
50
|
|
|
50
|
-
//# debugId=
|
|
51
|
+
//# debugId=8891BC0F1A79ABBB64756E2164756E21
|
|
51
52
|
//# sourceMappingURL=index.cjs.map
|