@btc-vision/transaction 1.0.84 → 1.0.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/.gitattributes +2 -2
  2. package/browser/_version.d.ts +1 -1
  3. package/browser/index.js +1 -1
  4. package/browser/keypair/Wallet.d.ts +3 -0
  5. package/browser/transaction/builders/TapUnwarpTransaction.d.ts +40 -40
  6. package/browser/transaction/builders/UnwarpTransaction.d.ts +34 -34
  7. package/browser/utxo/UTXOManager.d.ts +7 -7
  8. package/build/Utils.d.ts +0 -0
  9. package/build/Utils.js +1 -0
  10. package/build/_version.d.ts +1 -1
  11. package/build/_version.js +1 -1
  12. package/build/consensus/metadata/RoswsellConsensus.d.ts +2 -0
  13. package/build/consensus/metadata/RoswsellConsensus.js +4 -0
  14. package/build/contracts/ContractMetadataManager.d.ts +0 -0
  15. package/build/contracts/ContractMetadataManager.js +1 -0
  16. package/build/generators/OPNetAddressGenerator.d.ts +0 -0
  17. package/build/generators/OPNetAddressGenerator.js +1 -0
  18. package/build/generators/builders/UnwrapGenerator.d.ts +8 -0
  19. package/build/generators/builders/UnwrapGenerator.js +79 -0
  20. package/build/keypair/Wallet.d.ts +3 -0
  21. package/build/keypair/Wallet.js +8 -0
  22. package/build/keypair/interfaces/GeneratedWallet.d.ts +5 -0
  23. package/build/keypair/interfaces/GeneratedWallet.js +1 -0
  24. package/build/metadata/CommonContracts.d.ts +6 -0
  25. package/build/metadata/CommonContracts.js +5 -0
  26. package/build/metadata/ContractMetadataManager.d.ts +1 -0
  27. package/build/metadata/ContractMetadataManager.js +9 -0
  28. package/build/metadata/contracts/ContractBase.d.ts +9 -0
  29. package/build/metadata/contracts/ContractBase.js +13 -0
  30. package/build/metadata/contracts/ContractBaseMetadata.d.ts +9 -0
  31. package/build/metadata/contracts/ContractBaseMetadata.js +13 -0
  32. package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
  33. package/build/metadata/contracts/ContractMetadataManager.js +1 -0
  34. package/build/metadata/tokens.js +5 -5
  35. package/build/network/NetworkConverter.d.ts +0 -0
  36. package/build/network/NetworkConverter.js +14 -0
  37. package/build/scripts/Regtest.d.ts +2 -0
  38. package/build/scripts/Regtest.js +15 -0
  39. package/build/scripts/test.d.ts +1 -0
  40. package/build/scripts/test.js +74 -0
  41. package/build/signer/Regtest.d.ts +2 -0
  42. package/build/signer/Regtest.js +15 -0
  43. package/build/tests/Regtest.d.ts +3 -0
  44. package/build/tests/Regtest.js +29 -0
  45. package/build/tests/adaptPSBT.d.ts +1 -0
  46. package/build/tests/adaptPSBT.js +44 -0
  47. package/build/tests/btc/send.d.ts +1 -0
  48. package/build/tests/btc/send.js +35 -0
  49. package/build/tests/btc/transfer.d.ts +1 -0
  50. package/build/tests/btc/transfer.js +35 -0
  51. package/build/tests/createPairReg.d.ts +1 -0
  52. package/build/tests/createPairReg.js +73 -0
  53. package/build/tests/deploy/deployMoto.d.ts +4 -0
  54. package/build/tests/deploy/deployMoto.js +89 -0
  55. package/build/tests/deploy/deployPool.d.ts +1 -0
  56. package/build/tests/deploy/deployPool.js +5 -0
  57. package/build/tests/deploy/deployStep1.d.ts +1 -0
  58. package/build/tests/deploy/deployStep1.js +5 -0
  59. package/build/tests/deploy/deployStep2.d.ts +1 -0
  60. package/build/tests/deploy/deployStep2.js +5 -0
  61. package/build/tests/deploy/deployStep3.d.ts +1 -0
  62. package/build/tests/deploy/deployStep3.js +5 -0
  63. package/build/tests/deploy.d.ts +1 -0
  64. package/build/tests/deploy.js +41 -0
  65. package/build/tests/deployMotoRegStep1.d.ts +1 -0
  66. package/build/tests/deployMotoRegStep1.js +85 -0
  67. package/build/tests/deployReg.d.ts +1 -0
  68. package/build/tests/deployReg.js +85 -0
  69. package/build/tests/factory/createPairReg.d.ts +1 -0
  70. package/build/tests/factory/createPairReg.js +13 -0
  71. package/build/tests/gen.d.ts +1 -0
  72. package/build/tests/gen.js +19 -0
  73. package/build/tests/interaction.d.ts +5 -0
  74. package/build/tests/interaction.js +62 -0
  75. package/build/tests/massWrapReg.d.ts +1 -0
  76. package/build/tests/massWrapReg.js +105 -0
  77. package/build/tests/mineReg.d.ts +1 -0
  78. package/build/tests/mineReg.js +19 -0
  79. package/build/tests/moto/airdropToken.d.ts +1 -0
  80. package/build/tests/moto/airdropToken.js +21 -0
  81. package/build/tests/moto/airdropTokens.d.ts +1 -0
  82. package/build/tests/moto/airdropTokens.js +60 -0
  83. package/build/tests/moto/allowance.d.ts +1 -0
  84. package/build/tests/moto/allowance.js +6 -0
  85. package/build/tests/moto/approve.d.ts +1 -0
  86. package/build/tests/moto/approve.js +10 -0
  87. package/build/tests/moto/approveWBTC.d.ts +1 -0
  88. package/build/tests/moto/approveWBTC.js +12 -0
  89. package/build/tests/moto/balanceOf.d.ts +1 -0
  90. package/build/tests/moto/balanceOf.js +12 -0
  91. package/build/tests/moto/transfer.d.ts +1 -0
  92. package/build/tests/moto/transfer.js +16 -0
  93. package/build/tests/motoswap/airdropToken.d.ts +11 -0
  94. package/build/tests/motoswap/airdropToken.js +36 -0
  95. package/build/tests/motoswap/deployMoto.d.ts +4 -0
  96. package/build/tests/motoswap/deployMoto.js +89 -0
  97. package/build/tests/motoswap/deployMotoRegStep1.d.ts +1 -0
  98. package/build/tests/motoswap/deployMotoRegStep1.js +91 -0
  99. package/build/tests/motoswap/deployMotoRegStep2.d.ts +1 -0
  100. package/build/tests/motoswap/deployMotoRegStep2.js +91 -0
  101. package/build/tests/motoswap/deployPool.d.ts +1 -0
  102. package/build/tests/motoswap/deployPool.js +5 -0
  103. package/build/tests/motoswap/deployStep1.d.ts +1 -0
  104. package/build/tests/motoswap/deployStep1.js +5 -0
  105. package/build/tests/motoswap/deployStep2.d.ts +1 -0
  106. package/build/tests/motoswap/deployStep2.js +5 -0
  107. package/build/tests/motoswap/deployStep3.d.ts +1 -0
  108. package/build/tests/motoswap/deployStep3.js +5 -0
  109. package/build/tests/motoswap/interaction.d.ts +3 -0
  110. package/build/tests/motoswap/interaction.js +63 -0
  111. package/build/tests/motoswap/routerAddLiquidity.d.ts +11 -0
  112. package/build/tests/motoswap/routerAddLiquidity.js +35 -0
  113. package/build/tests/motoswap-router/addLiquidity.d.ts +11 -0
  114. package/build/tests/motoswap-router/addLiquidity.js +36 -0
  115. package/build/tests/motoswap-router/deployMoto.d.ts +4 -0
  116. package/build/tests/motoswap-router/deployMoto.js +89 -0
  117. package/build/tests/motoswap-router/deployPool.d.ts +1 -0
  118. package/build/tests/motoswap-router/deployPool.js +5 -0
  119. package/build/tests/motoswap-router/deployStep1.d.ts +1 -0
  120. package/build/tests/motoswap-router/deployStep1.js +5 -0
  121. package/build/tests/motoswap-router/deployStep2.d.ts +1 -0
  122. package/build/tests/motoswap-router/deployStep2.js +5 -0
  123. package/build/tests/motoswap-router/deployStep3.d.ts +1 -0
  124. package/build/tests/motoswap-router/deployStep3.js +5 -0
  125. package/build/tests/motoswap-router/getAmountsOut.d.ts +5 -0
  126. package/build/tests/motoswap-router/getAmountsOut.js +34 -0
  127. package/build/tests/motoswap-router/routerAddLiquidity.d.ts +11 -0
  128. package/build/tests/motoswap-router/routerAddLiquidity.js +35 -0
  129. package/build/tests/motoswap-router/swap.d.ts +8 -0
  130. package/build/tests/motoswap-router/swap.js +24 -0
  131. package/build/tests/multisign.d.ts +1 -0
  132. package/build/tests/multisign.js +47 -0
  133. package/build/tests/multisign2.d.ts +1 -0
  134. package/build/tests/multisign2.js +27 -0
  135. package/build/tests/pool/DecodePoolAddress.d.ts +6 -0
  136. package/build/tests/pool/DecodePoolAddress.js +12 -0
  137. package/build/tests/pool/decodeReserves.d.ts +5 -0
  138. package/build/tests/pool/decodeReserves.js +13 -0
  139. package/build/tests/pool/reserves.d.ts +1 -0
  140. package/build/tests/pool/reserves.js +18 -0
  141. package/build/tests/shared/Utils.d.ts +2 -0
  142. package/build/tests/shared/Utils.js +14 -0
  143. package/build/tests/shared/interaction.d.ts +7 -0
  144. package/build/tests/shared/interaction.js +85 -0
  145. package/build/tests/shared/tokens.d.ts +6 -0
  146. package/build/tests/shared/tokens.js +5 -0
  147. package/build/tests/stakeReg.d.ts +1 -0
  148. package/build/tests/stakeReg.js +73 -0
  149. package/build/tests/stakedReg.d.ts +1 -0
  150. package/build/tests/stakedReg.js +28 -0
  151. package/build/tests/test.d.ts +1 -0
  152. package/build/tests/test.js +51 -0
  153. package/build/tests/test2.d.ts +1 -0
  154. package/build/tests/test2.js +73 -0
  155. package/build/tests/testReg.d.ts +1 -0
  156. package/build/tests/testReg.js +91 -0
  157. package/build/tests/tokens.d.ts +6 -0
  158. package/build/tests/tokens.js +5 -0
  159. package/build/tests/totalRewardReg.d.ts +1 -0
  160. package/build/tests/totalRewardReg.js +28 -0
  161. package/build/tests/transfer.d.ts +1 -0
  162. package/build/tests/transfer.js +74 -0
  163. package/build/tests/transferReg.d.ts +1 -0
  164. package/build/tests/transferReg.js +74 -0
  165. package/build/tests/unStakeReg.d.ts +1 -0
  166. package/build/tests/unStakeReg.js +72 -0
  167. package/build/tests/unwrapReg.d.ts +1 -0
  168. package/build/tests/unwrapReg.js +61 -0
  169. package/build/tests/unwrapReg2.d.ts +1 -0
  170. package/build/tests/unwrapReg2.js +56 -0
  171. package/build/tests/unwrapRegSegwit.d.ts +1 -0
  172. package/build/tests/unwrapRegSegwit.js +83 -0
  173. package/build/tests/wbtc/approve.d.ts +1 -0
  174. package/build/tests/wbtc/approve.js +6 -0
  175. package/build/tests/wbtc/approveWBTC.d.ts +1 -0
  176. package/build/tests/wbtc/approveWBTC.js +12 -0
  177. package/build/tests/wbtc/massWrapReg.d.ts +1 -0
  178. package/build/tests/wbtc/massWrapReg.js +105 -0
  179. package/build/tests/wbtc/transfer.d.ts +1 -0
  180. package/build/tests/wbtc/transfer.js +16 -0
  181. package/build/tests/wbtc/transferReg.d.ts +1 -0
  182. package/build/tests/wbtc/transferReg.js +16 -0
  183. package/build/tests/wbtc/unStakeReg.d.ts +1 -0
  184. package/build/tests/wbtc/unStakeReg.js +72 -0
  185. package/build/tests/wbtc/unwrapReg.d.ts +1 -0
  186. package/build/tests/wbtc/unwrapReg.js +60 -0
  187. package/build/tests/wbtc/unwrapRegSegwit.d.ts +1 -0
  188. package/build/tests/wbtc/unwrapRegSegwit.js +83 -0
  189. package/build/tests/wbtc/withdrawalRequestReg.d.ts +1 -0
  190. package/build/tests/wbtc/withdrawalRequestReg.js +71 -0
  191. package/build/tests/wbtc/wrapReg.d.ts +1 -0
  192. package/build/tests/wbtc/wrapReg.js +65 -0
  193. package/build/tests/wbtc/wrapTest.d.ts +1 -0
  194. package/build/tests/wbtc/wrapTest.js +66 -0
  195. package/build/tests/withdrawalRequestReg.d.ts +1 -0
  196. package/build/tests/withdrawalRequestReg.js +71 -0
  197. package/build/tests/wrap.d.ts +1 -0
  198. package/build/tests/wrap.js +65 -0
  199. package/build/tests/wrapReg.d.ts +1 -0
  200. package/build/tests/wrapReg.js +68 -0
  201. package/build/tests/wrapTest.d.ts +1 -0
  202. package/build/tests/wrapTest.js +66 -0
  203. package/build/tests/wrapTestg.d.ts +1 -0
  204. package/build/tests/wrapTestg.js +66 -0
  205. package/build/tests/writers/allowance.d.ts +3 -0
  206. package/build/tests/writers/allowance.js +10 -0
  207. package/build/tests/writers/approve.d.ts +4 -0
  208. package/build/tests/writers/approve.js +11 -0
  209. package/build/transaction/TransactionBuilder.d.ts +60 -0
  210. package/build/transaction/TransactionBuilder.js +244 -0
  211. package/build/transaction/browser/BrowserSigner.d.ts +11 -0
  212. package/build/transaction/browser/BrowserSigner.js +10 -0
  213. package/build/transaction/browser/extensions/Unisat.d.ts +54 -0
  214. package/build/transaction/browser/extensions/Unisat.js +11 -0
  215. package/build/transaction/builders/GenericTransaction.d.ts +11 -0
  216. package/build/transaction/builders/GenericTransaction.js +23 -0
  217. package/build/transaction/builders/TapUnwarpTransaction.d.ts +37 -0
  218. package/build/transaction/builders/TapUnwarpTransaction.js +201 -0
  219. package/build/transaction/builders/UnwarpSegwitTransaction.d.ts +34 -0
  220. package/build/transaction/builders/UnwarpSegwitTransaction.js +184 -0
  221. package/build/transaction/builders/UnwarpTransaction.d.ts +35 -0
  222. package/build/transaction/builders/UnwarpTransaction.js +199 -0
  223. package/build/transaction/interfaces/ITransactions.d.ts +32 -0
  224. package/build/transaction/interfaces/ITransactions.js +1 -0
  225. package/build/utxo/IUTXO.d.ts +0 -0
  226. package/build/utxo/IUTXO.js +1 -0
  227. package/build/utxo/OPNetUtils.d.ts +7 -0
  228. package/build/utxo/OPNetUtils.js +47 -0
  229. package/build/utxo/UTXOManager.d.ts +7 -0
  230. package/build/utxo/UTXOManager.js +47 -0
  231. package/build/wbtc/BroadcastResponse.d.ts +0 -0
  232. package/build/wbtc/BroadcastResponse.js +1 -0
  233. package/gulpfile.js +152 -152
  234. package/package.json +109 -109
  235. package/src/_version.ts +1 -1
  236. package/src/consensus/Consensus.ts +36 -36
  237. package/src/consensus/ConsensusConfig.ts +39 -39
  238. package/src/crypto/crypto-browser.js +75 -75
  239. package/src/generators/AddressGenerator.ts +24 -24
  240. package/src/generators/Features.ts +5 -5
  241. package/src/generators/Generator.ts +75 -75
  242. package/src/generators/builders/CalldataGenerator.ts +148 -148
  243. package/src/generators/builders/DeploymentGenerator.ts +66 -66
  244. package/src/index.ts +4 -4
  245. package/src/keypair/AddressVerificator.ts +40 -40
  246. package/src/keypair/EcKeyPair.ts +282 -282
  247. package/src/keypair/Wallet.ts +120 -97
  248. package/src/keypair/interfaces/IWallet.ts +19 -19
  249. package/src/metadata/ContractBaseMetadata.ts +23 -23
  250. package/src/metadata/contracts/wBTC.ts +60 -60
  251. package/src/metadata/tokens.ts +135 -135
  252. package/src/network/NetworkInformation.ts +7 -7
  253. package/src/transaction/TransactionFactory.ts +496 -496
  254. package/src/transaction/browser/BrowserSignerBase.ts +37 -37
  255. package/src/transaction/browser/Web3Provider.ts +46 -46
  256. package/src/transaction/browser/extensions/UnisatSigner.ts +218 -218
  257. package/src/transaction/browser/types/Unisat.ts +97 -97
  258. package/src/transaction/builders/FundingTransaction.ts +40 -40
  259. package/src/transaction/builders/InteractionTransaction.ts +38 -38
  260. package/src/transaction/builders/SharedInteractionTransaction.ts +368 -368
  261. package/src/transaction/builders/TransactionBuilder.ts +665 -665
  262. package/src/transaction/builders/UnwrapSegwitTransaction.ts +365 -365
  263. package/src/transaction/builders/UnwrapTransaction.ts +507 -507
  264. package/src/transaction/builders/WrapTransaction.ts +346 -346
  265. package/src/transaction/interfaces/ITransactionParameters.ts +59 -59
  266. package/src/transaction/interfaces/Tap.ts +26 -26
  267. package/src/transaction/psbt/PSBTTypes.ts +3 -3
  268. package/src/transaction/shared/TweakedTransaction.ts +539 -539
  269. package/src/utxo/OPNetLimitedProvider.ts +244 -244
  270. package/src/utxo/interfaces/BroadcastResponse.ts +10 -10
  271. package/src/utxo/interfaces/IUTXO.ts +29 -29
  272. package/src/verification/TapscriptVerificator.ts +89 -89
  273. package/src/wbtc/Generate.ts +40 -40
  274. package/src/wbtc/UnwrapGeneration.ts +13 -13
  275. package/src/wbtc/WrappedGenerationParameters.ts +33 -33
  276. package/webpack.config.js +78 -78
  277. /package/build/generators/builders/{MultiSignGenerator.d.ts → MultisignGenerator.d.ts} +0 -0
  278. /package/build/generators/builders/{MultiSignGenerator.js → MultisignGenerator.js} +0 -0
  279. /package/build/generators/{Features.d.ts → features.d.ts} +0 -0
  280. /package/build/generators/{Features.js → features.js} +0 -0
@@ -1,539 +1,539 @@
1
- import { Logger } from '@btc-vision/logger';
2
- import { Network, Payment, payments, Psbt, Signer, Transaction } from 'bitcoinjs-lib';
3
- import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
4
- import { ECPairInterface } from 'ecpair';
5
- import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
6
- import { PsbtInput } from 'bip174/src/lib/interfaces.js';
7
- import { UTXO } from '../../utxo/interfaces/IUTXO.js';
8
- import { PsbtInputExtended, TapLeafScript } from '../interfaces/Tap.js';
9
- import { AddressVerificator } from '../../keypair/AddressVerificator.js';
10
- import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
11
- import { ChainId } from '../../network/ChainId.js';
12
-
13
- export interface ITweakedTransactionData {
14
- readonly signer: Signer;
15
- readonly network: Network;
16
- readonly chainId?: ChainId;
17
- readonly nonWitnessUtxo?: Buffer;
18
- }
19
-
20
- /**
21
- * The transaction sequence
22
- */
23
- export enum TransactionSequence {
24
- REPLACE_BY_FEE = 0xfffffffd,
25
- FINAL = 0xffffffff,
26
- }
27
-
28
- /**
29
- * @description PSBT Transaction processor.
30
- * */
31
- export abstract class TweakedTransaction extends Logger {
32
- public readonly logColor: string = '#00ffe1';
33
- public finalized: boolean = false;
34
- /**
35
- * @description Was the transaction signed?
36
- */
37
- protected signer: Signer;
38
- /**
39
- * @description Tweaked signer
40
- */
41
- protected tweakedSigner?: Signer;
42
- /**
43
- * @description The network of the transaction
44
- */
45
- protected network: Network;
46
- /**
47
- * @description Was the transaction signed?
48
- */
49
- protected signed: boolean = false;
50
- /**
51
- * @description The transaction
52
- * @protected
53
- */
54
- protected abstract readonly transaction: Psbt;
55
- /**
56
- * @description The sighash types of the transaction
57
- * @protected
58
- */
59
- protected sighashTypes: number[] | undefined;
60
- /**
61
- * @description The script data of the transaction
62
- */
63
- protected scriptData: Payment | null = null;
64
- /**
65
- * @description The tap data of the transaction
66
- */
67
- protected tapData: Payment | null = null;
68
- /**
69
- * @description The inputs of the transaction
70
- */
71
- protected readonly inputs: PsbtInputExtended[] = [];
72
- /**
73
- * @description The sequence of the transaction
74
- * @protected
75
- */
76
- protected sequence: number = TransactionSequence.REPLACE_BY_FEE;
77
- /**
78
- * The tap leaf script
79
- * @protected
80
- */
81
- protected tapLeafScript: TapLeafScript | null = null;
82
- /**
83
- * Add a non-witness utxo to the transaction
84
- * @protected
85
- */
86
- protected nonWitnessUtxo?: Buffer;
87
-
88
- /**
89
- * Is the transaction being generated inside a browser?
90
- * @protected
91
- */
92
- protected readonly isBrowser: boolean = false;
93
-
94
- protected regenerated: boolean = false;
95
- protected ignoreSignatureErrors: boolean = false;
96
-
97
- protected constructor(data: ITweakedTransactionData) {
98
- super();
99
-
100
- this.signer = data.signer;
101
- this.network = data.network;
102
-
103
- this.nonWitnessUtxo = data.nonWitnessUtxo;
104
-
105
- this.isBrowser = typeof window !== 'undefined';
106
- }
107
-
108
- /**
109
- * Read witnesses
110
- * @protected
111
- */
112
- public static readScriptWitnessToWitnessStack(buffer: Buffer): Buffer[] {
113
- let offset = 0;
114
-
115
- function readSlice(n: number): Buffer {
116
- const slice = buffer.subarray(offset, offset + n);
117
- offset += n;
118
- return slice;
119
- }
120
-
121
- function readVarInt(): number {
122
- const varint = varuint.decode(buffer, offset);
123
- offset += varuint.decode.bytes;
124
- return varint;
125
- }
126
-
127
- function readVarSlice(): Buffer {
128
- const len = readVarInt();
129
- return readSlice(len);
130
- }
131
-
132
- function readVector(): Buffer[] {
133
- const count = readVarInt();
134
- const vector = [];
135
- for (let i = 0; i < count; i++) {
136
- vector.push(readVarSlice());
137
- }
138
- return vector;
139
- }
140
-
141
- return readVector();
142
- }
143
-
144
- /**
145
- * Pre-estimate the transaction fees for a Taproot transaction
146
- * @param {bigint} feeRate - The fee rate in satoshis per virtual byte
147
- * @param {bigint} numInputs - The number of inputs
148
- * @param {bigint} numOutputs - The number of outputs
149
- * @param {bigint} numWitnessElements - The number of witness elements (e.g., number of control blocks and witnesses)
150
- * @param {bigint} witnessElementSize - The average size of each witness element in bytes
151
- * @param {bigint} emptyWitness - The amount of empty witnesses
152
- * @param {bigint} [taprootControlWitnessSize=139n] - The size of the control block witness in bytes
153
- * @param {bigint} [taprootScriptSize=32n] - The size of the taproot script in bytes
154
- * @returns {bigint} - The estimated transaction fees
155
- */
156
- public static preEstimateTaprootTransactionFees(
157
- feeRate: bigint, // satoshis per virtual byte
158
- numInputs: bigint,
159
- numOutputs: bigint,
160
- numWitnessElements: bigint,
161
- witnessElementSize: bigint,
162
- emptyWitness: bigint,
163
- taprootControlWitnessSize: bigint = 32n,
164
- taprootScriptSize: bigint = 139n,
165
- ): bigint {
166
- const txHeaderSize = 10n;
167
- const inputBaseSize = 41n;
168
- const outputSize = 68n;
169
- const taprootWitnessBaseSize = 1n; // Base witness size per input (without signatures and control blocks)
170
-
171
- // Base transaction size (excluding witness data)
172
- const baseTxSize = txHeaderSize + inputBaseSize * numInputs + outputSize * numOutputs;
173
-
174
- // Witness data size for Taproot
175
- const witnessSize =
176
- numInputs * taprootWitnessBaseSize +
177
- numWitnessElements * witnessElementSize +
178
- taprootControlWitnessSize * numInputs +
179
- taprootScriptSize * numInputs +
180
- emptyWitness;
181
-
182
- // Total weight and virtual size
183
- const weight = baseTxSize * 3n + (baseTxSize + witnessSize);
184
- const vSize = weight / 4n;
185
-
186
- return vSize * feeRate;
187
- }
188
-
189
- protected static signInput(
190
- transaction: Psbt,
191
- input: PsbtInput,
192
- i: number,
193
- signer: Signer,
194
- sighashTypes: number[],
195
- ): void {
196
- if (sighashTypes && sighashTypes[0]) input.sighashType = sighashTypes[0];
197
-
198
- transaction.signInput(i, signer, sighashTypes.length ? sighashTypes : undefined);
199
- }
200
-
201
- /**
202
- * Calculate the sign hash number
203
- * @description Calculates the sign hash
204
- * @protected
205
- * @returns {number}
206
- */
207
- protected static calculateSignHash(sighashTypes: number[]): number {
208
- if (!sighashTypes) {
209
- throw new Error('Sighash types are required');
210
- }
211
-
212
- let signHash: number = 0;
213
- for (let sighashType of sighashTypes) {
214
- signHash |= sighashType;
215
- }
216
-
217
- return signHash || 0;
218
- }
219
-
220
- public ignoreSignatureError(): void {
221
- this.ignoreSignatureErrors = true;
222
- }
223
-
224
- /**
225
- * @description Returns the script address
226
- * @returns {string}
227
- */
228
- public getScriptAddress(): string {
229
- if (!this.scriptData || !this.scriptData.address) {
230
- throw new Error('Tap data is required');
231
- }
232
-
233
- return this.scriptData.address;
234
- }
235
-
236
- /**
237
- * @description Returns the transaction
238
- * @returns {Transaction}
239
- */
240
- public getTransaction(): Transaction {
241
- return this.transaction.extractTransaction(false);
242
- }
243
-
244
- /**
245
- * @description Returns the tap address
246
- * @returns {string}
247
- * @throws {Error} - If tap data is not set
248
- */
249
- public getTapAddress(): string {
250
- if (!this.tapData || !this.tapData.address) {
251
- throw new Error('Tap data is required');
252
- }
253
-
254
- return this.tapData.address;
255
- }
256
-
257
- /**
258
- * @description Disables replace by fee on the transaction
259
- */
260
- public disableRBF(): void {
261
- if (this.signed) throw new Error('Transaction is already signed');
262
-
263
- this.sequence = TransactionSequence.FINAL;
264
-
265
- for (let input of this.inputs) {
266
- input.sequence = TransactionSequence.FINAL;
267
- }
268
- }
269
-
270
- /**
271
- * Get the tweaked hash
272
- * @private
273
- *
274
- * @returns {Buffer | undefined} The tweaked hash
275
- */
276
- public getTweakerHash(): Buffer | undefined {
277
- return this.tapData?.hash;
278
- }
279
-
280
- /**
281
- * Pre-estimate the transaction fees
282
- * @param {bigint} feeRate - The fee rate
283
- * @param {bigint} numInputs - The number of inputs
284
- * @param {bigint} numOutputs - The number of outputs
285
- * @param {bigint} numSignatures - The number of signatures
286
- * @param {bigint} numPubkeys - The number of public keys
287
- * @returns {bigint} - The estimated transaction fees
288
- */
289
- public preEstimateTransactionFees(
290
- feeRate: bigint, // satoshis per byte
291
- numInputs: bigint,
292
- numOutputs: bigint,
293
- numSignatures: bigint,
294
- numPubkeys: bigint,
295
- ): bigint {
296
- const txHeaderSize = 10n;
297
- const inputBaseSize = 41n;
298
- const outputSize = 68n;
299
- const signatureSize = 144n;
300
- const pubkeySize = 34n;
301
-
302
- // Base transaction size (excluding witness data)
303
- const baseTxSize = txHeaderSize + inputBaseSize * numInputs + outputSize * numOutputs;
304
-
305
- // Witness data size
306
- const redeemScriptSize = 1n + numPubkeys * (1n + pubkeySize) + 1n + numSignatures;
307
- const witnessSize =
308
- numSignatures * signatureSize + numPubkeys * pubkeySize + redeemScriptSize;
309
-
310
- // Total weight and virtual size
311
- const weight = baseTxSize * 3n + (baseTxSize + witnessSize);
312
- const vSize = weight / 4n;
313
-
314
- return vSize * feeRate;
315
- }
316
-
317
- protected generateTapData(): Payment {
318
- return {
319
- internalPubkey: this.internalPubKeyToXOnly(),
320
- network: this.network,
321
- };
322
- }
323
-
324
- /**
325
- * Generates the script address.
326
- * @protected
327
- * @returns {Payment}
328
- */
329
- protected generateScriptAddress(): Payment {
330
- return {
331
- internalPubkey: this.internalPubKeyToXOnly(),
332
- network: this.network,
333
- };
334
- }
335
-
336
- /**
337
- * Returns the signer key.
338
- * @protected
339
- * @returns {Signer}
340
- */
341
- protected getSignerKey(): Signer {
342
- return this.signer;
343
- }
344
-
345
- /**
346
- * Signs an input of the transaction.
347
- * @param {Psbt} transaction - The transaction to sign
348
- * @param {PsbtInput} input - The input to sign
349
- * @param {number} i - The index of the input
350
- * @param {Signer} [signer] - The signer to use
351
- * @protected
352
- */
353
- protected async signInput(
354
- transaction: Psbt,
355
- input: PsbtInput,
356
- i: number,
357
- signer?: Signer,
358
- ): Promise<void> {
359
- const signHash =
360
- this.sighashTypes && this.sighashTypes.length
361
- ? [TweakedTransaction.calculateSignHash(this.sighashTypes)]
362
- : undefined;
363
-
364
- signer = signer || this.getSignerKey();
365
-
366
- let testedTap: boolean = false;
367
- if (input.tapInternalKey) {
368
- if (!this.tweakedSigner) this.tweakSigner();
369
-
370
- let tweakedSigner: Signer | undefined;
371
- if (signer !== this.signer) {
372
- tweakedSigner = this.getTweakedSigner(true, signer);
373
- } else {
374
- tweakedSigner = this.tweakedSigner;
375
- }
376
-
377
- if (tweakedSigner) {
378
- testedTap = true;
379
-
380
- try {
381
- if ('signTaprootInput' in signer) {
382
- // @ts-ignore
383
- return await signer.signTaprootInput(transaction, i, signHash);
384
- } else {
385
- transaction.signTaprootInput(i, tweakedSigner, undefined, signHash);
386
- }
387
-
388
- return;
389
- } catch (e) {}
390
- }
391
- }
392
-
393
- try {
394
- if ('signInput' in signer) {
395
- // @ts-ignore
396
- return await signer.signInput(transaction, i, signHash);
397
- } else {
398
- transaction.signInput(i, signer, signHash);
399
- }
400
- } catch (e) {
401
- if (!testedTap) {
402
- // and we try again taproot...
403
-
404
- if ('signTaprootInput' in signer) {
405
- // @ts-ignore
406
- return await signer.signTaprootInput(transaction, i, signHash);
407
- } else if (this.tweakedSigner) {
408
- transaction.signTaprootInput(i, this.tweakedSigner, undefined, signHash);
409
- } else {
410
- throw e;
411
- }
412
- }
413
- }
414
- }
415
-
416
- /**
417
- * Signs all the inputs of the transaction.
418
- * @param {Psbt} transaction - The transaction to sign
419
- * @protected
420
- * @returns {Promise<void>}
421
- */
422
- protected async signInputs(transaction: Psbt): Promise<void> {
423
- for (let i = 0; i < transaction.data.inputs.length; i++) {
424
- let input: PsbtInput = transaction.data.inputs[i];
425
-
426
- try {
427
- await this.signInput(transaction, input, i);
428
- } catch (e) {
429
- this.log(`Failed to sign input ${i}: ${(e as Error).stack}`);
430
- }
431
- }
432
-
433
- try {
434
- transaction.finalizeAllInputs();
435
-
436
- this.finalized = true;
437
- } catch (e) {
438
- this.finalized = false;
439
- }
440
- }
441
-
442
- /**
443
- * Converts the public key to x-only.
444
- * @protected
445
- * @returns {Buffer}
446
- */
447
- protected internalPubKeyToXOnly(): Buffer {
448
- return toXOnly(this.signer.publicKey);
449
- }
450
-
451
- /**
452
- * Internal init.
453
- * @protected
454
- */
455
- protected internalInit(): void {
456
- this.scriptData = payments.p2tr(this.generateScriptAddress());
457
- this.tapData = payments.p2tr(this.generateTapData());
458
- }
459
-
460
- /**
461
- * Tweak the signer for the interaction
462
- * @protected
463
- */
464
- protected tweakSigner(): void {
465
- if (this.tweakedSigner) return;
466
-
467
- // tweaked p2tr signer.
468
- this.tweakedSigner = this.getTweakedSigner(true);
469
- }
470
-
471
- /**
472
- * Get the tweaked signer
473
- * @private
474
- * @returns {Signer} The tweaked signer
475
- */
476
- protected getTweakedSigner(
477
- useTweakedHash: boolean = false,
478
- signer: Signer = this.signer,
479
- ): Signer | undefined {
480
- const settings: TweakSettings = {
481
- network: this.network,
482
- };
483
-
484
- if (useTweakedHash) {
485
- settings.tweakHash = this.getTweakerHash();
486
- }
487
-
488
- if (!('privateKey' in signer)) {
489
- return;
490
- }
491
-
492
- return TweakedSigner.tweakSigner(signer as unknown as ECPairInterface, settings) as Signer;
493
- }
494
-
495
- /**
496
- * Generate the PSBT input extended
497
- * @param {UTXO} utxo The UTXO
498
- * @param {number} i The index of the input
499
- * @protected
500
- * @returns {PsbtInputExtended} The PSBT input extended
501
- */
502
- protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended {
503
- const input: PsbtInputExtended = {
504
- hash: utxo.transactionId,
505
- index: utxo.outputIndex,
506
- witnessUtxo: {
507
- value: Number(utxo.value),
508
- script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
509
- },
510
- sequence: this.sequence,
511
- };
512
-
513
- if (this.sighashTypes) {
514
- const inputSign = TweakedTransaction.calculateSignHash(this.sighashTypes);
515
- if (inputSign) input.sighashType = inputSign;
516
- }
517
-
518
- if (this.tapLeafScript) {
519
- input.tapLeafScript = [this.tapLeafScript];
520
- }
521
-
522
- if (i === 0 && this.nonWitnessUtxo) {
523
- input.nonWitnessUtxo = this.nonWitnessUtxo;
524
- this.log(`Using non-witness utxo for input ${i}`);
525
- }
526
-
527
- // automatically detect p2tr inputs.
528
- if (
529
- utxo.scriptPubKey.address &&
530
- AddressVerificator.isValidP2TRAddress(utxo.scriptPubKey.address, this.network)
531
- ) {
532
- this.tweakSigner();
533
-
534
- input.tapInternalKey = this.internalPubKeyToXOnly();
535
- }
536
-
537
- return input;
538
- }
539
- }
1
+ import { Logger } from '@btc-vision/logger';
2
+ import { Network, Payment, payments, Psbt, Signer, Transaction } from 'bitcoinjs-lib';
3
+ import { TweakedSigner, TweakSettings } from '../../signer/TweakedSigner.js';
4
+ import { ECPairInterface } from 'ecpair';
5
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
6
+ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
7
+ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
8
+ import { PsbtInputExtended, TapLeafScript } from '../interfaces/Tap.js';
9
+ import { AddressVerificator } from '../../keypair/AddressVerificator.js';
10
+ import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
11
+ import { ChainId } from '../../network/ChainId.js';
12
+
13
+ export interface ITweakedTransactionData {
14
+ readonly signer: Signer;
15
+ readonly network: Network;
16
+ readonly chainId?: ChainId;
17
+ readonly nonWitnessUtxo?: Buffer;
18
+ }
19
+
20
+ /**
21
+ * The transaction sequence
22
+ */
23
+ export enum TransactionSequence {
24
+ REPLACE_BY_FEE = 0xfffffffd,
25
+ FINAL = 0xffffffff,
26
+ }
27
+
28
+ /**
29
+ * @description PSBT Transaction processor.
30
+ * */
31
+ export abstract class TweakedTransaction extends Logger {
32
+ public readonly logColor: string = '#00ffe1';
33
+ public finalized: boolean = false;
34
+ /**
35
+ * @description Was the transaction signed?
36
+ */
37
+ protected signer: Signer;
38
+ /**
39
+ * @description Tweaked signer
40
+ */
41
+ protected tweakedSigner?: Signer;
42
+ /**
43
+ * @description The network of the transaction
44
+ */
45
+ protected network: Network;
46
+ /**
47
+ * @description Was the transaction signed?
48
+ */
49
+ protected signed: boolean = false;
50
+ /**
51
+ * @description The transaction
52
+ * @protected
53
+ */
54
+ protected abstract readonly transaction: Psbt;
55
+ /**
56
+ * @description The sighash types of the transaction
57
+ * @protected
58
+ */
59
+ protected sighashTypes: number[] | undefined;
60
+ /**
61
+ * @description The script data of the transaction
62
+ */
63
+ protected scriptData: Payment | null = null;
64
+ /**
65
+ * @description The tap data of the transaction
66
+ */
67
+ protected tapData: Payment | null = null;
68
+ /**
69
+ * @description The inputs of the transaction
70
+ */
71
+ protected readonly inputs: PsbtInputExtended[] = [];
72
+ /**
73
+ * @description The sequence of the transaction
74
+ * @protected
75
+ */
76
+ protected sequence: number = TransactionSequence.REPLACE_BY_FEE;
77
+ /**
78
+ * The tap leaf script
79
+ * @protected
80
+ */
81
+ protected tapLeafScript: TapLeafScript | null = null;
82
+ /**
83
+ * Add a non-witness utxo to the transaction
84
+ * @protected
85
+ */
86
+ protected nonWitnessUtxo?: Buffer;
87
+
88
+ /**
89
+ * Is the transaction being generated inside a browser?
90
+ * @protected
91
+ */
92
+ protected readonly isBrowser: boolean = false;
93
+
94
+ protected regenerated: boolean = false;
95
+ protected ignoreSignatureErrors: boolean = false;
96
+
97
+ protected constructor(data: ITweakedTransactionData) {
98
+ super();
99
+
100
+ this.signer = data.signer;
101
+ this.network = data.network;
102
+
103
+ this.nonWitnessUtxo = data.nonWitnessUtxo;
104
+
105
+ this.isBrowser = typeof window !== 'undefined';
106
+ }
107
+
108
+ /**
109
+ * Read witnesses
110
+ * @protected
111
+ */
112
+ public static readScriptWitnessToWitnessStack(buffer: Buffer): Buffer[] {
113
+ let offset = 0;
114
+
115
+ function readSlice(n: number): Buffer {
116
+ const slice = buffer.subarray(offset, offset + n);
117
+ offset += n;
118
+ return slice;
119
+ }
120
+
121
+ function readVarInt(): number {
122
+ const varint = varuint.decode(buffer, offset);
123
+ offset += varuint.decode.bytes;
124
+ return varint;
125
+ }
126
+
127
+ function readVarSlice(): Buffer {
128
+ const len = readVarInt();
129
+ return readSlice(len);
130
+ }
131
+
132
+ function readVector(): Buffer[] {
133
+ const count = readVarInt();
134
+ const vector = [];
135
+ for (let i = 0; i < count; i++) {
136
+ vector.push(readVarSlice());
137
+ }
138
+ return vector;
139
+ }
140
+
141
+ return readVector();
142
+ }
143
+
144
+ /**
145
+ * Pre-estimate the transaction fees for a Taproot transaction
146
+ * @param {bigint} feeRate - The fee rate in satoshis per virtual byte
147
+ * @param {bigint} numInputs - The number of inputs
148
+ * @param {bigint} numOutputs - The number of outputs
149
+ * @param {bigint} numWitnessElements - The number of witness elements (e.g., number of control blocks and witnesses)
150
+ * @param {bigint} witnessElementSize - The average size of each witness element in bytes
151
+ * @param {bigint} emptyWitness - The amount of empty witnesses
152
+ * @param {bigint} [taprootControlWitnessSize=139n] - The size of the control block witness in bytes
153
+ * @param {bigint} [taprootScriptSize=32n] - The size of the taproot script in bytes
154
+ * @returns {bigint} - The estimated transaction fees
155
+ */
156
+ public static preEstimateTaprootTransactionFees(
157
+ feeRate: bigint, // satoshis per virtual byte
158
+ numInputs: bigint,
159
+ numOutputs: bigint,
160
+ numWitnessElements: bigint,
161
+ witnessElementSize: bigint,
162
+ emptyWitness: bigint,
163
+ taprootControlWitnessSize: bigint = 32n,
164
+ taprootScriptSize: bigint = 139n,
165
+ ): bigint {
166
+ const txHeaderSize = 10n;
167
+ const inputBaseSize = 41n;
168
+ const outputSize = 68n;
169
+ const taprootWitnessBaseSize = 1n; // Base witness size per input (without signatures and control blocks)
170
+
171
+ // Base transaction size (excluding witness data)
172
+ const baseTxSize = txHeaderSize + inputBaseSize * numInputs + outputSize * numOutputs;
173
+
174
+ // Witness data size for Taproot
175
+ const witnessSize =
176
+ numInputs * taprootWitnessBaseSize +
177
+ numWitnessElements * witnessElementSize +
178
+ taprootControlWitnessSize * numInputs +
179
+ taprootScriptSize * numInputs +
180
+ emptyWitness;
181
+
182
+ // Total weight and virtual size
183
+ const weight = baseTxSize * 3n + (baseTxSize + witnessSize);
184
+ const vSize = weight / 4n;
185
+
186
+ return vSize * feeRate;
187
+ }
188
+
189
+ protected static signInput(
190
+ transaction: Psbt,
191
+ input: PsbtInput,
192
+ i: number,
193
+ signer: Signer,
194
+ sighashTypes: number[],
195
+ ): void {
196
+ if (sighashTypes && sighashTypes[0]) input.sighashType = sighashTypes[0];
197
+
198
+ transaction.signInput(i, signer, sighashTypes.length ? sighashTypes : undefined);
199
+ }
200
+
201
+ /**
202
+ * Calculate the sign hash number
203
+ * @description Calculates the sign hash
204
+ * @protected
205
+ * @returns {number}
206
+ */
207
+ protected static calculateSignHash(sighashTypes: number[]): number {
208
+ if (!sighashTypes) {
209
+ throw new Error('Sighash types are required');
210
+ }
211
+
212
+ let signHash: number = 0;
213
+ for (let sighashType of sighashTypes) {
214
+ signHash |= sighashType;
215
+ }
216
+
217
+ return signHash || 0;
218
+ }
219
+
220
+ public ignoreSignatureError(): void {
221
+ this.ignoreSignatureErrors = true;
222
+ }
223
+
224
+ /**
225
+ * @description Returns the script address
226
+ * @returns {string}
227
+ */
228
+ public getScriptAddress(): string {
229
+ if (!this.scriptData || !this.scriptData.address) {
230
+ throw new Error('Tap data is required');
231
+ }
232
+
233
+ return this.scriptData.address;
234
+ }
235
+
236
+ /**
237
+ * @description Returns the transaction
238
+ * @returns {Transaction}
239
+ */
240
+ public getTransaction(): Transaction {
241
+ return this.transaction.extractTransaction(false);
242
+ }
243
+
244
+ /**
245
+ * @description Returns the tap address
246
+ * @returns {string}
247
+ * @throws {Error} - If tap data is not set
248
+ */
249
+ public getTapAddress(): string {
250
+ if (!this.tapData || !this.tapData.address) {
251
+ throw new Error('Tap data is required');
252
+ }
253
+
254
+ return this.tapData.address;
255
+ }
256
+
257
+ /**
258
+ * @description Disables replace by fee on the transaction
259
+ */
260
+ public disableRBF(): void {
261
+ if (this.signed) throw new Error('Transaction is already signed');
262
+
263
+ this.sequence = TransactionSequence.FINAL;
264
+
265
+ for (let input of this.inputs) {
266
+ input.sequence = TransactionSequence.FINAL;
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Get the tweaked hash
272
+ * @private
273
+ *
274
+ * @returns {Buffer | undefined} The tweaked hash
275
+ */
276
+ public getTweakerHash(): Buffer | undefined {
277
+ return this.tapData?.hash;
278
+ }
279
+
280
+ /**
281
+ * Pre-estimate the transaction fees
282
+ * @param {bigint} feeRate - The fee rate
283
+ * @param {bigint} numInputs - The number of inputs
284
+ * @param {bigint} numOutputs - The number of outputs
285
+ * @param {bigint} numSignatures - The number of signatures
286
+ * @param {bigint} numPubkeys - The number of public keys
287
+ * @returns {bigint} - The estimated transaction fees
288
+ */
289
+ public preEstimateTransactionFees(
290
+ feeRate: bigint, // satoshis per byte
291
+ numInputs: bigint,
292
+ numOutputs: bigint,
293
+ numSignatures: bigint,
294
+ numPubkeys: bigint,
295
+ ): bigint {
296
+ const txHeaderSize = 10n;
297
+ const inputBaseSize = 41n;
298
+ const outputSize = 68n;
299
+ const signatureSize = 144n;
300
+ const pubkeySize = 34n;
301
+
302
+ // Base transaction size (excluding witness data)
303
+ const baseTxSize = txHeaderSize + inputBaseSize * numInputs + outputSize * numOutputs;
304
+
305
+ // Witness data size
306
+ const redeemScriptSize = 1n + numPubkeys * (1n + pubkeySize) + 1n + numSignatures;
307
+ const witnessSize =
308
+ numSignatures * signatureSize + numPubkeys * pubkeySize + redeemScriptSize;
309
+
310
+ // Total weight and virtual size
311
+ const weight = baseTxSize * 3n + (baseTxSize + witnessSize);
312
+ const vSize = weight / 4n;
313
+
314
+ return vSize * feeRate;
315
+ }
316
+
317
+ protected generateTapData(): Payment {
318
+ return {
319
+ internalPubkey: this.internalPubKeyToXOnly(),
320
+ network: this.network,
321
+ };
322
+ }
323
+
324
+ /**
325
+ * Generates the script address.
326
+ * @protected
327
+ * @returns {Payment}
328
+ */
329
+ protected generateScriptAddress(): Payment {
330
+ return {
331
+ internalPubkey: this.internalPubKeyToXOnly(),
332
+ network: this.network,
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Returns the signer key.
338
+ * @protected
339
+ * @returns {Signer}
340
+ */
341
+ protected getSignerKey(): Signer {
342
+ return this.signer;
343
+ }
344
+
345
+ /**
346
+ * Signs an input of the transaction.
347
+ * @param {Psbt} transaction - The transaction to sign
348
+ * @param {PsbtInput} input - The input to sign
349
+ * @param {number} i - The index of the input
350
+ * @param {Signer} [signer] - The signer to use
351
+ * @protected
352
+ */
353
+ protected async signInput(
354
+ transaction: Psbt,
355
+ input: PsbtInput,
356
+ i: number,
357
+ signer?: Signer,
358
+ ): Promise<void> {
359
+ const signHash =
360
+ this.sighashTypes && this.sighashTypes.length
361
+ ? [TweakedTransaction.calculateSignHash(this.sighashTypes)]
362
+ : undefined;
363
+
364
+ signer = signer || this.getSignerKey();
365
+
366
+ let testedTap: boolean = false;
367
+ if (input.tapInternalKey) {
368
+ if (!this.tweakedSigner) this.tweakSigner();
369
+
370
+ let tweakedSigner: Signer | undefined;
371
+ if (signer !== this.signer) {
372
+ tweakedSigner = this.getTweakedSigner(true, signer);
373
+ } else {
374
+ tweakedSigner = this.tweakedSigner;
375
+ }
376
+
377
+ if (tweakedSigner) {
378
+ testedTap = true;
379
+
380
+ try {
381
+ if ('signTaprootInput' in signer) {
382
+ // @ts-ignore
383
+ return await signer.signTaprootInput(transaction, i, signHash);
384
+ } else {
385
+ transaction.signTaprootInput(i, tweakedSigner, undefined, signHash);
386
+ }
387
+
388
+ return;
389
+ } catch (e) {}
390
+ }
391
+ }
392
+
393
+ try {
394
+ if ('signInput' in signer) {
395
+ // @ts-ignore
396
+ return await signer.signInput(transaction, i, signHash);
397
+ } else {
398
+ transaction.signInput(i, signer, signHash);
399
+ }
400
+ } catch (e) {
401
+ if (!testedTap) {
402
+ // and we try again taproot...
403
+
404
+ if ('signTaprootInput' in signer) {
405
+ // @ts-ignore
406
+ return await signer.signTaprootInput(transaction, i, signHash);
407
+ } else if (this.tweakedSigner) {
408
+ transaction.signTaprootInput(i, this.tweakedSigner, undefined, signHash);
409
+ } else {
410
+ throw e;
411
+ }
412
+ }
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Signs all the inputs of the transaction.
418
+ * @param {Psbt} transaction - The transaction to sign
419
+ * @protected
420
+ * @returns {Promise<void>}
421
+ */
422
+ protected async signInputs(transaction: Psbt): Promise<void> {
423
+ for (let i = 0; i < transaction.data.inputs.length; i++) {
424
+ let input: PsbtInput = transaction.data.inputs[i];
425
+
426
+ try {
427
+ await this.signInput(transaction, input, i);
428
+ } catch (e) {
429
+ this.log(`Failed to sign input ${i}: ${(e as Error).stack}`);
430
+ }
431
+ }
432
+
433
+ try {
434
+ transaction.finalizeAllInputs();
435
+
436
+ this.finalized = true;
437
+ } catch (e) {
438
+ this.finalized = false;
439
+ }
440
+ }
441
+
442
+ /**
443
+ * Converts the public key to x-only.
444
+ * @protected
445
+ * @returns {Buffer}
446
+ */
447
+ protected internalPubKeyToXOnly(): Buffer {
448
+ return toXOnly(this.signer.publicKey);
449
+ }
450
+
451
+ /**
452
+ * Internal init.
453
+ * @protected
454
+ */
455
+ protected internalInit(): void {
456
+ this.scriptData = payments.p2tr(this.generateScriptAddress());
457
+ this.tapData = payments.p2tr(this.generateTapData());
458
+ }
459
+
460
+ /**
461
+ * Tweak the signer for the interaction
462
+ * @protected
463
+ */
464
+ protected tweakSigner(): void {
465
+ if (this.tweakedSigner) return;
466
+
467
+ // tweaked p2tr signer.
468
+ this.tweakedSigner = this.getTweakedSigner(true);
469
+ }
470
+
471
+ /**
472
+ * Get the tweaked signer
473
+ * @private
474
+ * @returns {Signer} The tweaked signer
475
+ */
476
+ protected getTweakedSigner(
477
+ useTweakedHash: boolean = false,
478
+ signer: Signer = this.signer,
479
+ ): Signer | undefined {
480
+ const settings: TweakSettings = {
481
+ network: this.network,
482
+ };
483
+
484
+ if (useTweakedHash) {
485
+ settings.tweakHash = this.getTweakerHash();
486
+ }
487
+
488
+ if (!('privateKey' in signer)) {
489
+ return;
490
+ }
491
+
492
+ return TweakedSigner.tweakSigner(signer as unknown as ECPairInterface, settings) as Signer;
493
+ }
494
+
495
+ /**
496
+ * Generate the PSBT input extended
497
+ * @param {UTXO} utxo The UTXO
498
+ * @param {number} i The index of the input
499
+ * @protected
500
+ * @returns {PsbtInputExtended} The PSBT input extended
501
+ */
502
+ protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended {
503
+ const input: PsbtInputExtended = {
504
+ hash: utxo.transactionId,
505
+ index: utxo.outputIndex,
506
+ witnessUtxo: {
507
+ value: Number(utxo.value),
508
+ script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
509
+ },
510
+ sequence: this.sequence,
511
+ };
512
+
513
+ if (this.sighashTypes) {
514
+ const inputSign = TweakedTransaction.calculateSignHash(this.sighashTypes);
515
+ if (inputSign) input.sighashType = inputSign;
516
+ }
517
+
518
+ if (this.tapLeafScript) {
519
+ input.tapLeafScript = [this.tapLeafScript];
520
+ }
521
+
522
+ if (i === 0 && this.nonWitnessUtxo) {
523
+ input.nonWitnessUtxo = this.nonWitnessUtxo;
524
+ this.log(`Using non-witness utxo for input ${i}`);
525
+ }
526
+
527
+ // automatically detect p2tr inputs.
528
+ if (
529
+ utxo.scriptPubKey.address &&
530
+ AddressVerificator.isValidP2TRAddress(utxo.scriptPubKey.address, this.network)
531
+ ) {
532
+ this.tweakSigner();
533
+
534
+ input.tapInternalKey = this.internalPubKeyToXOnly();
535
+ }
536
+
537
+ return input;
538
+ }
539
+ }