@dynamic-labs/bitcoin 4.52.5 → 4.53.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 +16 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +11 -6
- package/src/connectors/BitcoinSatsConnectConnector/BitcoinSatsConnectConnector.js +1 -1
- package/src/connectors/BitcoinWalletConnector.cjs +8 -0
- package/src/connectors/BitcoinWalletConnector.d.ts +1 -0
- package/src/connectors/BitcoinWalletConnector.js +10 -2
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +464 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +314 -0
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +460 -0
- package/src/connectors/DynamicWaasBitcoinConnector/index.d.ts +1 -0
- package/src/connectors/index.d.ts +1 -0
- package/src/const.cjs +13 -0
- package/src/const.d.ts +6 -0
- package/src/const.js +8 -1
- package/src/index.cjs +9 -0
- package/src/index.d.ts +2 -2
- package/src/index.js +6 -0
- package/src/services/MempoolApiService.cjs +127 -0
- package/src/services/MempoolApiService.d.ts +42 -0
- package/src/services/MempoolApiService.js +123 -0
- package/src/services/PsbtBuilderService.cjs +132 -0
- package/src/services/PsbtBuilderService.d.ts +27 -0
- package/src/services/PsbtBuilderService.js +124 -0
- package/src/types.d.ts +43 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.cjs +24 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.d.ts +7 -0
- package/src/utils/btcToSatoshis/btcToSatoshis.js +20 -0
- package/src/utils/btcToSatoshis/index.d.ts +1 -0
- package/src/utils/fetchSatsConnectConnectors/fetchSatsConnectConnectors.cjs +1 -0
- package/src/utils/fetchSatsConnectConnectors/fetchSatsConnectConnectors.js +1 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.cjs +15 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.d.ts +7 -0
- package/src/utils/getBitcoinNetwork/getBitcoinNetwork.js +11 -0
- package/src/utils/getBitcoinNetwork/index.d.ts +1 -0
- package/src/utils/index.d.ts +3 -0
- package/src/utils/psbtParser/PsbtParser.cjs +185 -0
- package/src/utils/psbtParser/PsbtParser.d.ts +63 -0
- package/src/utils/psbtParser/PsbtParser.js +181 -0
- package/src/utils/psbtParser/index.d.ts +1 -0
- package/src/wallet/BitcoinWallet.cjs +11 -0
- package/src/wallet/BitcoinWallet.d.ts +6 -0
- package/src/wallet/BitcoinWallet.js +11 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { DynamicError } from '@dynamic-labs/utils';
|
|
3
|
+
import { SATOSHIS_PER_BTC } from '../../const.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Helper function to convert BTC amount to satoshis
|
|
7
|
+
* @param btcAmount - The Bitcoin amount to convert (number)
|
|
8
|
+
* @returns The amount in satoshis as a BigInt
|
|
9
|
+
* @throws {DynamicError} If the amount is negative
|
|
10
|
+
*/
|
|
11
|
+
const btcToSatoshis = (btcAmount) => {
|
|
12
|
+
if (btcAmount < 0) {
|
|
13
|
+
throw new DynamicError('BTC amount cannot be negative');
|
|
14
|
+
}
|
|
15
|
+
// Convert to satoshis and return as BigInt
|
|
16
|
+
const satoshis = Math.floor(btcAmount * SATOSHIS_PER_BTC);
|
|
17
|
+
return BigInt(satoshis);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { btcToSatoshis };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { btcToSatoshis } from './btcToSatoshis';
|
|
@@ -14,6 +14,7 @@ var _const = require('../../const.cjs');
|
|
|
14
14
|
require('bitcoinjs-lib');
|
|
15
15
|
var BitcoinSatsConnectConnector = require('../../connectors/BitcoinSatsConnectConnector/BitcoinSatsConnectConnector.cjs');
|
|
16
16
|
require('jsontokens');
|
|
17
|
+
require('../../connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs');
|
|
17
18
|
|
|
18
19
|
const fetchSatsConnectConnectors = ({ walletBook, }) => {
|
|
19
20
|
var _a;
|
|
@@ -10,6 +10,7 @@ import { SATSCONNECT_FEATURE } from '../../const.js';
|
|
|
10
10
|
import 'bitcoinjs-lib';
|
|
11
11
|
import { BitcoinSatsConnectConnector } from '../../connectors/BitcoinSatsConnectConnector/BitcoinSatsConnectConnector.js';
|
|
12
12
|
import 'jsontokens';
|
|
13
|
+
import '../../connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js';
|
|
13
14
|
|
|
14
15
|
const fetchSatsConnectConnectors = ({ walletBook, }) => {
|
|
15
16
|
var _a;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var bitcoinjsLib = require('bitcoinjs-lib');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Gets the Bitcoin network based on address prefix
|
|
10
|
+
* @param accountAddress - The Bitcoin address
|
|
11
|
+
* @returns The Bitcoin network (mainnet or testnet)
|
|
12
|
+
*/
|
|
13
|
+
const getBitcoinNetwork = (accountAddress) => accountAddress.startsWith('t') ? bitcoinjsLib.networks.testnet : bitcoinjsLib.networks.bitcoin;
|
|
14
|
+
|
|
15
|
+
exports.getBitcoinNetwork = getBitcoinNetwork;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Network } from 'bitcoinjs-lib';
|
|
2
|
+
/**
|
|
3
|
+
* Gets the Bitcoin network based on address prefix
|
|
4
|
+
* @param accountAddress - The Bitcoin address
|
|
5
|
+
* @returns The Bitcoin network (mainnet or testnet)
|
|
6
|
+
*/
|
|
7
|
+
export declare const getBitcoinNetwork: (accountAddress: string) => Network;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { networks } from 'bitcoinjs-lib';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Gets the Bitcoin network based on address prefix
|
|
6
|
+
* @param accountAddress - The Bitcoin address
|
|
7
|
+
* @returns The Bitcoin network (mainnet or testnet)
|
|
8
|
+
*/
|
|
9
|
+
const getBitcoinNetwork = (accountAddress) => accountAddress.startsWith('t') ? networks.testnet : networks.bitcoin;
|
|
10
|
+
|
|
11
|
+
export { getBitcoinNetwork };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getBitcoinNetwork } from './getBitcoinNetwork';
|
package/src/utils/index.d.ts
CHANGED
|
@@ -4,3 +4,6 @@ export { hasSatsConnectFeature } from './hasSatsConnectFeature';
|
|
|
4
4
|
export { getMempoolApiUrl } from './getMempoolApiUrl';
|
|
5
5
|
export { createPsbtOptions } from './psbt/createSignPsbtOptions';
|
|
6
6
|
export { satoshisToBtc } from './satoshisToBtc';
|
|
7
|
+
export { btcToSatoshis } from './btcToSatoshis';
|
|
8
|
+
export { getBitcoinNetwork } from './getBitcoinNetwork';
|
|
9
|
+
export { PsbtParser } from './psbtParser';
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var bitcoinjsLib = require('bitcoinjs-lib');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Utility class for parsing PSBTs and finalized Bitcoin transactions
|
|
10
|
+
*/
|
|
11
|
+
class PsbtParser {
|
|
12
|
+
/**
|
|
13
|
+
* Parse a PSBT or finalized transaction and extract transaction information
|
|
14
|
+
* Auto-detects format (hex/base64) and type (PSBT/finalized transaction)
|
|
15
|
+
* @param psbtInput - The PSBT or finalized transaction in Base64 or hex format
|
|
16
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
17
|
+
* @throws Error if parsing fails
|
|
18
|
+
*/
|
|
19
|
+
static parsePsbt(psbtInput) {
|
|
20
|
+
const isHex = /^[0-9a-fA-F]+$/.test(psbtInput) && psbtInput.length > 100;
|
|
21
|
+
if (isHex) {
|
|
22
|
+
return PsbtParser.parseHexPsbt(psbtInput);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return PsbtParser.parseBase64Psbt(psbtInput);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse a PSBT or finalized transaction from hex format
|
|
30
|
+
* @param psbtHex - The PSBT or finalized transaction in hex format
|
|
31
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
32
|
+
* @throws Error if parsing fails
|
|
33
|
+
*/
|
|
34
|
+
static parseHexPsbt(psbtHex) {
|
|
35
|
+
try {
|
|
36
|
+
try {
|
|
37
|
+
const psbt = bitcoinjsLib.Psbt.fromHex(psbtHex, { network: bitcoinjsLib.networks.bitcoin });
|
|
38
|
+
return PsbtParser.extractPsbtData(psbt);
|
|
39
|
+
}
|
|
40
|
+
catch (psbtError) {
|
|
41
|
+
return PsbtParser.parseFinalizedTransactionHex(psbtHex);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new Error(`Failed to parse hex PSBT: ${error instanceof Error ? error.message : String(error)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse a PSBT or finalized transaction from base64 format
|
|
50
|
+
* @param psbtBase64 - The PSBT or finalized transaction in base64 format
|
|
51
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
52
|
+
* @throws Error if parsing fails
|
|
53
|
+
*/
|
|
54
|
+
static parseBase64Psbt(psbtBase64) {
|
|
55
|
+
try {
|
|
56
|
+
try {
|
|
57
|
+
const psbt = bitcoinjsLib.Psbt.fromBase64(psbtBase64, { network: bitcoinjsLib.networks.bitcoin });
|
|
58
|
+
return PsbtParser.extractPsbtData(psbt);
|
|
59
|
+
}
|
|
60
|
+
catch (psbtError) {
|
|
61
|
+
return PsbtParser.parseFinalizedTransactionBase64(psbtBase64);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw new Error(`Failed to parse base64 PSBT: ${error instanceof Error ? error.message : String(error)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extract transaction data from a PSBT
|
|
70
|
+
* Shared logic used by both parseHexPsbt and parseBase64Psbt
|
|
71
|
+
* @param psbt - The parsed PSBT object
|
|
72
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
73
|
+
*/
|
|
74
|
+
static extractPsbtData(psbt) {
|
|
75
|
+
const inputs = [];
|
|
76
|
+
const outputs = [];
|
|
77
|
+
psbt.txInputs.forEach((txInput, index) => {
|
|
78
|
+
const input = psbt.data.inputs[index];
|
|
79
|
+
const inputData = {
|
|
80
|
+
txid: txInput.hash.reverse().toString('hex'),
|
|
81
|
+
vout: txInput.index,
|
|
82
|
+
};
|
|
83
|
+
if (input.witnessUtxo) {
|
|
84
|
+
inputData.value = input.witnessUtxo.value;
|
|
85
|
+
try {
|
|
86
|
+
inputData.address = bitcoinjsLib.address.fromOutputScript(input.witnessUtxo.script, bitcoinjsLib.networks.bitcoin);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
// Address extraction failed
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else if (input.nonWitnessUtxo) {
|
|
93
|
+
try {
|
|
94
|
+
const prevTx = bitcoinjsLib.Transaction.fromBuffer(input.nonWitnessUtxo);
|
|
95
|
+
const prevOut = prevTx.outs[txInput.index];
|
|
96
|
+
inputData.value = prevOut.value;
|
|
97
|
+
try {
|
|
98
|
+
inputData.address = bitcoinjsLib.address.fromOutputScript(prevOut.script, bitcoinjsLib.networks.bitcoin);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
// Address extraction failed
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
// Transaction parsing failed
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
inputs.push(inputData);
|
|
109
|
+
});
|
|
110
|
+
PsbtParser.extractOutputs(psbt.txOutputs, outputs);
|
|
111
|
+
return { inputs, outputs };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Extract outputs from transaction outputs
|
|
115
|
+
* Shared logic used by both PSBT and finalized transaction parsing
|
|
116
|
+
* @param txOutputs - Array of transaction outputs (from PSBT or Transaction)
|
|
117
|
+
* @param outputs - Array to populate with parsed output data
|
|
118
|
+
*/
|
|
119
|
+
static extractOutputs(txOutputs, outputs) {
|
|
120
|
+
txOutputs.forEach((txOutput) => {
|
|
121
|
+
const outputData = {
|
|
122
|
+
value: txOutput.value,
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
outputData.address = bitcoinjsLib.address.fromOutputScript(txOutput.script, bitcoinjsLib.networks.bitcoin);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
// Address extraction failed - continue without address
|
|
129
|
+
}
|
|
130
|
+
outputs.push(outputData);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Parse a finalized Bitcoin transaction from hex format
|
|
135
|
+
* @param txHex - The transaction in hex format
|
|
136
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
137
|
+
* @throws Error if parsing fails
|
|
138
|
+
*/
|
|
139
|
+
static parseFinalizedTransactionHex(txHex) {
|
|
140
|
+
try {
|
|
141
|
+
const tx = bitcoinjsLib.Transaction.fromHex(txHex);
|
|
142
|
+
return PsbtParser.extractTransactionData(tx);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
throw new Error(`Failed to parse finalized transaction hex: ${error instanceof Error ? error.message : String(error)}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Parse a finalized Bitcoin transaction from base64 format
|
|
150
|
+
* @param txBase64 - The transaction in base64 format
|
|
151
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
152
|
+
* @throws Error if parsing fails
|
|
153
|
+
*/
|
|
154
|
+
static parseFinalizedTransactionBase64(txBase64) {
|
|
155
|
+
try {
|
|
156
|
+
const buffer = Buffer.from(txBase64, 'base64');
|
|
157
|
+
const tx = bitcoinjsLib.Transaction.fromBuffer(buffer);
|
|
158
|
+
return PsbtParser.extractTransactionData(tx);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
throw new Error(`Failed to parse finalized transaction base64: ${error instanceof Error ? error.message : String(error)}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Extract transaction data from a finalized Transaction
|
|
166
|
+
* Shared logic used by both parseFinalizedTransactionHex and parseFinalizedTransactionBase64
|
|
167
|
+
* @param tx - The parsed Transaction object
|
|
168
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
169
|
+
*/
|
|
170
|
+
static extractTransactionData(tx) {
|
|
171
|
+
const inputs = [];
|
|
172
|
+
const outputs = [];
|
|
173
|
+
tx.ins.forEach((input) => {
|
|
174
|
+
const inputData = {
|
|
175
|
+
txid: input.hash.reverse().toString('hex'),
|
|
176
|
+
vout: input.index,
|
|
177
|
+
};
|
|
178
|
+
inputs.push(inputData);
|
|
179
|
+
});
|
|
180
|
+
PsbtParser.extractOutputs(tx.outs, outputs);
|
|
181
|
+
return { inputs, outputs };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
exports.PsbtParser = PsbtParser;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ParsedTransaction } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Utility class for parsing PSBTs and finalized Bitcoin transactions
|
|
4
|
+
*/
|
|
5
|
+
export declare class PsbtParser {
|
|
6
|
+
/**
|
|
7
|
+
* Parse a PSBT or finalized transaction and extract transaction information
|
|
8
|
+
* Auto-detects format (hex/base64) and type (PSBT/finalized transaction)
|
|
9
|
+
* @param psbtInput - The PSBT or finalized transaction in Base64 or hex format
|
|
10
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
11
|
+
* @throws Error if parsing fails
|
|
12
|
+
*/
|
|
13
|
+
static parsePsbt(psbtInput: string): ParsedTransaction;
|
|
14
|
+
/**
|
|
15
|
+
* Parse a PSBT or finalized transaction from hex format
|
|
16
|
+
* @param psbtHex - The PSBT or finalized transaction in hex format
|
|
17
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
18
|
+
* @throws Error if parsing fails
|
|
19
|
+
*/
|
|
20
|
+
static parseHexPsbt(psbtHex: string): ParsedTransaction;
|
|
21
|
+
/**
|
|
22
|
+
* Parse a PSBT or finalized transaction from base64 format
|
|
23
|
+
* @param psbtBase64 - The PSBT or finalized transaction in base64 format
|
|
24
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
25
|
+
* @throws Error if parsing fails
|
|
26
|
+
*/
|
|
27
|
+
static parseBase64Psbt(psbtBase64: string): ParsedTransaction;
|
|
28
|
+
/**
|
|
29
|
+
* Extract transaction data from a PSBT
|
|
30
|
+
* Shared logic used by both parseHexPsbt and parseBase64Psbt
|
|
31
|
+
* @param psbt - The parsed PSBT object
|
|
32
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
33
|
+
*/
|
|
34
|
+
private static extractPsbtData;
|
|
35
|
+
/**
|
|
36
|
+
* Extract outputs from transaction outputs
|
|
37
|
+
* Shared logic used by both PSBT and finalized transaction parsing
|
|
38
|
+
* @param txOutputs - Array of transaction outputs (from PSBT or Transaction)
|
|
39
|
+
* @param outputs - Array to populate with parsed output data
|
|
40
|
+
*/
|
|
41
|
+
private static extractOutputs;
|
|
42
|
+
/**
|
|
43
|
+
* Parse a finalized Bitcoin transaction from hex format
|
|
44
|
+
* @param txHex - The transaction in hex format
|
|
45
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
46
|
+
* @throws Error if parsing fails
|
|
47
|
+
*/
|
|
48
|
+
private static parseFinalizedTransactionHex;
|
|
49
|
+
/**
|
|
50
|
+
* Parse a finalized Bitcoin transaction from base64 format
|
|
51
|
+
* @param txBase64 - The transaction in base64 format
|
|
52
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
53
|
+
* @throws Error if parsing fails
|
|
54
|
+
*/
|
|
55
|
+
private static parseFinalizedTransactionBase64;
|
|
56
|
+
/**
|
|
57
|
+
* Extract transaction data from a finalized Transaction
|
|
58
|
+
* Shared logic used by both parseFinalizedTransactionHex and parseFinalizedTransactionBase64
|
|
59
|
+
* @param tx - The parsed Transaction object
|
|
60
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
61
|
+
*/
|
|
62
|
+
private static extractTransactionData;
|
|
63
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { Psbt, networks, address, Transaction } from 'bitcoinjs-lib';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility class for parsing PSBTs and finalized Bitcoin transactions
|
|
6
|
+
*/
|
|
7
|
+
class PsbtParser {
|
|
8
|
+
/**
|
|
9
|
+
* Parse a PSBT or finalized transaction and extract transaction information
|
|
10
|
+
* Auto-detects format (hex/base64) and type (PSBT/finalized transaction)
|
|
11
|
+
* @param psbtInput - The PSBT or finalized transaction in Base64 or hex format
|
|
12
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
13
|
+
* @throws Error if parsing fails
|
|
14
|
+
*/
|
|
15
|
+
static parsePsbt(psbtInput) {
|
|
16
|
+
const isHex = /^[0-9a-fA-F]+$/.test(psbtInput) && psbtInput.length > 100;
|
|
17
|
+
if (isHex) {
|
|
18
|
+
return PsbtParser.parseHexPsbt(psbtInput);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return PsbtParser.parseBase64Psbt(psbtInput);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a PSBT or finalized transaction from hex format
|
|
26
|
+
* @param psbtHex - The PSBT or finalized transaction in hex format
|
|
27
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
28
|
+
* @throws Error if parsing fails
|
|
29
|
+
*/
|
|
30
|
+
static parseHexPsbt(psbtHex) {
|
|
31
|
+
try {
|
|
32
|
+
try {
|
|
33
|
+
const psbt = Psbt.fromHex(psbtHex, { network: networks.bitcoin });
|
|
34
|
+
return PsbtParser.extractPsbtData(psbt);
|
|
35
|
+
}
|
|
36
|
+
catch (psbtError) {
|
|
37
|
+
return PsbtParser.parseFinalizedTransactionHex(psbtHex);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error(`Failed to parse hex PSBT: ${error instanceof Error ? error.message : String(error)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse a PSBT or finalized transaction from base64 format
|
|
46
|
+
* @param psbtBase64 - The PSBT or finalized transaction in base64 format
|
|
47
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
48
|
+
* @throws Error if parsing fails
|
|
49
|
+
*/
|
|
50
|
+
static parseBase64Psbt(psbtBase64) {
|
|
51
|
+
try {
|
|
52
|
+
try {
|
|
53
|
+
const psbt = Psbt.fromBase64(psbtBase64, { network: networks.bitcoin });
|
|
54
|
+
return PsbtParser.extractPsbtData(psbt);
|
|
55
|
+
}
|
|
56
|
+
catch (psbtError) {
|
|
57
|
+
return PsbtParser.parseFinalizedTransactionBase64(psbtBase64);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
throw new Error(`Failed to parse base64 PSBT: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Extract transaction data from a PSBT
|
|
66
|
+
* Shared logic used by both parseHexPsbt and parseBase64Psbt
|
|
67
|
+
* @param psbt - The parsed PSBT object
|
|
68
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
69
|
+
*/
|
|
70
|
+
static extractPsbtData(psbt) {
|
|
71
|
+
const inputs = [];
|
|
72
|
+
const outputs = [];
|
|
73
|
+
psbt.txInputs.forEach((txInput, index) => {
|
|
74
|
+
const input = psbt.data.inputs[index];
|
|
75
|
+
const inputData = {
|
|
76
|
+
txid: txInput.hash.reverse().toString('hex'),
|
|
77
|
+
vout: txInput.index,
|
|
78
|
+
};
|
|
79
|
+
if (input.witnessUtxo) {
|
|
80
|
+
inputData.value = input.witnessUtxo.value;
|
|
81
|
+
try {
|
|
82
|
+
inputData.address = address.fromOutputScript(input.witnessUtxo.script, networks.bitcoin);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
// Address extraction failed
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (input.nonWitnessUtxo) {
|
|
89
|
+
try {
|
|
90
|
+
const prevTx = Transaction.fromBuffer(input.nonWitnessUtxo);
|
|
91
|
+
const prevOut = prevTx.outs[txInput.index];
|
|
92
|
+
inputData.value = prevOut.value;
|
|
93
|
+
try {
|
|
94
|
+
inputData.address = address.fromOutputScript(prevOut.script, networks.bitcoin);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// Address extraction failed
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
// Transaction parsing failed
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
inputs.push(inputData);
|
|
105
|
+
});
|
|
106
|
+
PsbtParser.extractOutputs(psbt.txOutputs, outputs);
|
|
107
|
+
return { inputs, outputs };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Extract outputs from transaction outputs
|
|
111
|
+
* Shared logic used by both PSBT and finalized transaction parsing
|
|
112
|
+
* @param txOutputs - Array of transaction outputs (from PSBT or Transaction)
|
|
113
|
+
* @param outputs - Array to populate with parsed output data
|
|
114
|
+
*/
|
|
115
|
+
static extractOutputs(txOutputs, outputs) {
|
|
116
|
+
txOutputs.forEach((txOutput) => {
|
|
117
|
+
const outputData = {
|
|
118
|
+
value: txOutput.value,
|
|
119
|
+
};
|
|
120
|
+
try {
|
|
121
|
+
outputData.address = address.fromOutputScript(txOutput.script, networks.bitcoin);
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
// Address extraction failed - continue without address
|
|
125
|
+
}
|
|
126
|
+
outputs.push(outputData);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Parse a finalized Bitcoin transaction from hex format
|
|
131
|
+
* @param txHex - The transaction in hex format
|
|
132
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
133
|
+
* @throws Error if parsing fails
|
|
134
|
+
*/
|
|
135
|
+
static parseFinalizedTransactionHex(txHex) {
|
|
136
|
+
try {
|
|
137
|
+
const tx = Transaction.fromHex(txHex);
|
|
138
|
+
return PsbtParser.extractTransactionData(tx);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw new Error(`Failed to parse finalized transaction hex: ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Parse a finalized Bitcoin transaction from base64 format
|
|
146
|
+
* @param txBase64 - The transaction in base64 format
|
|
147
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
148
|
+
* @throws Error if parsing fails
|
|
149
|
+
*/
|
|
150
|
+
static parseFinalizedTransactionBase64(txBase64) {
|
|
151
|
+
try {
|
|
152
|
+
const buffer = Buffer.from(txBase64, 'base64');
|
|
153
|
+
const tx = Transaction.fromBuffer(buffer);
|
|
154
|
+
return PsbtParser.extractTransactionData(tx);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
throw new Error(`Failed to parse finalized transaction base64: ${error instanceof Error ? error.message : String(error)}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Extract transaction data from a finalized Transaction
|
|
162
|
+
* Shared logic used by both parseFinalizedTransactionHex and parseFinalizedTransactionBase64
|
|
163
|
+
* @param tx - The parsed Transaction object
|
|
164
|
+
* @returns Parsed transaction data with inputs and outputs
|
|
165
|
+
*/
|
|
166
|
+
static extractTransactionData(tx) {
|
|
167
|
+
const inputs = [];
|
|
168
|
+
const outputs = [];
|
|
169
|
+
tx.ins.forEach((input) => {
|
|
170
|
+
const inputData = {
|
|
171
|
+
txid: input.hash.reverse().toString('hex'),
|
|
172
|
+
vout: input.index,
|
|
173
|
+
};
|
|
174
|
+
inputs.push(inputData);
|
|
175
|
+
});
|
|
176
|
+
PsbtParser.extractOutputs(tx.outs, outputs);
|
|
177
|
+
return { inputs, outputs };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export { PsbtParser };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PsbtParser } from './PsbtParser';
|
|
@@ -85,6 +85,17 @@ class BitcoinWallet extends walletConnectorCore.Wallet {
|
|
|
85
85
|
return this._connector.signPsbts(requests);
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Builds a PSBT for a Bitcoin transaction
|
|
90
|
+
* @param transaction - The Bitcoin transaction containing recipient address and amount in satoshis
|
|
91
|
+
* @returns A promise that resolves to a PSBT in Base64 format, or undefined if not supported
|
|
92
|
+
*/
|
|
93
|
+
buildPsbt(transaction) {
|
|
94
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
yield this.sync();
|
|
96
|
+
return this._connector.buildPsbt(transaction);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
88
99
|
}
|
|
89
100
|
|
|
90
101
|
exports.BitcoinWallet = BitcoinWallet;
|
|
@@ -48,4 +48,10 @@ export declare class BitcoinWallet extends Wallet<BitcoinWalletConnector> {
|
|
|
48
48
|
* or undefined if no provider is available
|
|
49
49
|
*/
|
|
50
50
|
signPsbts(requests: BitcoinSignPsbtRequest[]): Promise<string[] | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Builds a PSBT for a Bitcoin transaction
|
|
53
|
+
* @param transaction - The Bitcoin transaction containing recipient address and amount in satoshis
|
|
54
|
+
* @returns A promise that resolves to a PSBT in Base64 format, or undefined if not supported
|
|
55
|
+
*/
|
|
56
|
+
buildPsbt(transaction: BitcoinTransaction): Promise<string | undefined>;
|
|
51
57
|
}
|
|
@@ -81,6 +81,17 @@ class BitcoinWallet extends Wallet {
|
|
|
81
81
|
return this._connector.signPsbts(requests);
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Builds a PSBT for a Bitcoin transaction
|
|
86
|
+
* @param transaction - The Bitcoin transaction containing recipient address and amount in satoshis
|
|
87
|
+
* @returns A promise that resolves to a PSBT in Base64 format, or undefined if not supported
|
|
88
|
+
*/
|
|
89
|
+
buildPsbt(transaction) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
yield this.sync();
|
|
92
|
+
return this._connector.buildPsbt(transaction);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
export { BitcoinWallet };
|