beignet 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc +40 -0
  3. package/.prettierrc +9 -0
  4. package/LICENSE +21 -0
  5. package/README.md +166 -0
  6. package/dist/electrum/constants.js +31 -0
  7. package/dist/electrum/constants.js.map +1 -0
  8. package/dist/electrum/index.js +552 -0
  9. package/dist/electrum/index.js.map +1 -0
  10. package/dist/index.js +23 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/shapes/electrum.js +14 -0
  13. package/dist/shapes/electrum.js.map +1 -0
  14. package/dist/shapes/index.js +19 -0
  15. package/dist/shapes/index.js.map +1 -0
  16. package/dist/shapes/wallet.js +115 -0
  17. package/dist/shapes/wallet.js.map +1 -0
  18. package/dist/transaction/index.js +692 -0
  19. package/dist/transaction/index.js.map +1 -0
  20. package/dist/types/electrum/constants.d.ts +7 -0
  21. package/dist/types/electrum/index.d.ts +85 -0
  22. package/dist/types/electrum.js +9 -0
  23. package/dist/types/electrum.js.map +1 -0
  24. package/dist/types/index.d.ts +6 -0
  25. package/dist/types/index.js +20 -0
  26. package/dist/types/index.js.map +1 -0
  27. package/dist/types/shapes/electrum.d.ts +5 -0
  28. package/dist/types/shapes/index.d.ts +2 -0
  29. package/dist/types/shapes/wallet.d.ts +10 -0
  30. package/dist/types/transaction/index.d.ts +92 -0
  31. package/dist/types/transaction.js +12 -0
  32. package/dist/types/transaction.js.map +1 -0
  33. package/dist/types/types/electrum.d.ts +113 -0
  34. package/dist/types/types/index.d.ts +3 -0
  35. package/dist/types/types/transaction.d.ts +51 -0
  36. package/dist/types/types/wallet.d.ts +400 -0
  37. package/dist/types/utils/conversion.d.ts +10 -0
  38. package/dist/types/utils/derivation-path.d.ts +19 -0
  39. package/dist/types/utils/electrum.d.ts +10 -0
  40. package/dist/types/utils/exchange-rate.d.ts +30 -0
  41. package/dist/types/utils/helpers.d.ts +23 -0
  42. package/dist/types/utils/index.d.ts +7 -0
  43. package/dist/types/utils/result.d.ts +16 -0
  44. package/dist/types/utils/transaction.d.ts +21 -0
  45. package/dist/types/utils/wallet.d.ts +47 -0
  46. package/dist/types/wallet/constants.d.ts +12 -0
  47. package/dist/types/wallet/index.d.ts +214 -0
  48. package/dist/types/wallet.js +36 -0
  49. package/dist/types/wallet.js.map +1 -0
  50. package/dist/utils/conversion.js +52 -0
  51. package/dist/utils/conversion.js.map +1 -0
  52. package/dist/utils/derivation-path.js +104 -0
  53. package/dist/utils/derivation-path.js.map +1 -0
  54. package/dist/utils/electrum.js +149 -0
  55. package/dist/utils/electrum.js.map +1 -0
  56. package/dist/utils/exchange-rate.js +49 -0
  57. package/dist/utils/exchange-rate.js.map +1 -0
  58. package/dist/utils/helpers.js +137 -0
  59. package/dist/utils/helpers.js.map +1 -0
  60. package/dist/utils/index.js +24 -0
  61. package/dist/utils/index.js.map +1 -0
  62. package/dist/utils/result.js +36 -0
  63. package/dist/utils/result.js.map +1 -0
  64. package/dist/utils/transaction.js +327 -0
  65. package/dist/utils/transaction.js.map +1 -0
  66. package/dist/utils/wallet.js +227 -0
  67. package/dist/utils/wallet.js.map +1 -0
  68. package/dist/wallet/constants.js +15 -0
  69. package/dist/wallet/constants.js.map +1 -0
  70. package/dist/wallet/index.js +2113 -0
  71. package/dist/wallet/index.js.map +1 -0
  72. package/docs/html/.nojekyll +1 -0
  73. package/docs/html/assets/highlight.css +22 -0
  74. package/docs/html/assets/main.js +58 -0
  75. package/docs/html/assets/search.js +1 -0
  76. package/docs/html/assets/style.css +1367 -0
  77. package/docs/html/classes/Electrum.html +812 -0
  78. package/docs/html/classes/Transaction.html +687 -0
  79. package/docs/html/classes/Wallet.html +2030 -0
  80. package/docs/html/enums/EAddressType.html +227 -0
  81. package/docs/html/enums/EAvailableNetworks.html +255 -0
  82. package/docs/html/enums/EBoostType.html +220 -0
  83. package/docs/html/enums/EFeeId.html +241 -0
  84. package/docs/html/enums/EPaymentType.html +220 -0
  85. package/docs/html/enums/EProtocol.html +220 -0
  86. package/docs/html/enums/EUnit.html +227 -0
  87. package/docs/html/functions/availableNetworks.html +200 -0
  88. package/docs/html/functions/constructByteCountParam.html +210 -0
  89. package/docs/html/functions/decodeOpReturnMessage.html +202 -0
  90. package/docs/html/functions/decodeRawTransaction.html +210 -0
  91. package/docs/html/functions/err.html +214 -0
  92. package/docs/html/functions/formatKeyDerivationPath.html +219 -0
  93. package/docs/html/functions/formatPeerData.html +207 -0
  94. package/docs/html/functions/generateMnemonic.html +223 -0
  95. package/docs/html/functions/generateWalletId.html +202 -0
  96. package/docs/html/functions/getAddressFromScriptPubKey.html +209 -0
  97. package/docs/html/functions/getAddressTypeFromPath.html +206 -0
  98. package/docs/html/functions/getByteCount.html +206 -0
  99. package/docs/html/functions/getDataFallback.html +207 -0
  100. package/docs/html/functions/getDefaultPort.html +209 -0
  101. package/docs/html/functions/getDefaultWalletData.html +200 -0
  102. package/docs/html/functions/getDefaultWalletDataKeys.html +200 -0
  103. package/docs/html/functions/getExchangeRates.html +200 -0
  104. package/docs/html/functions/getHighestUsedIndexFromTxHashes.html +216 -0
  105. package/docs/html/functions/getKeyDerivationPath.html +211 -0
  106. package/docs/html/functions/getKeyDerivationPathObject.html +216 -0
  107. package/docs/html/functions/getKeyDerivationPathString.html +220 -0
  108. package/docs/html/functions/getKeyValue.html +206 -0
  109. package/docs/html/functions/getPeers.html +211 -0
  110. package/docs/html/functions/getProtocolForPort.html +209 -0
  111. package/docs/html/functions/getScriptHash.html +210 -0
  112. package/docs/html/functions/getSeed.html +209 -0
  113. package/docs/html/functions/getSeedHash.html +206 -0
  114. package/docs/html/functions/getSha256.html +206 -0
  115. package/docs/html/functions/getStorageKeyValues.html +209 -0
  116. package/docs/html/functions/getTxFee.html +210 -0
  117. package/docs/html/functions/getWalletDataStorageKey.html +206 -0
  118. package/docs/html/functions/isValidBech32mEncodedString.html +211 -0
  119. package/docs/html/functions/objectKeys-1.html +211 -0
  120. package/docs/html/functions/objectsMatch.html +210 -0
  121. package/docs/html/functions/ok.html +214 -0
  122. package/docs/html/functions/parseOnChainPaymentRequest.html +204 -0
  123. package/docs/html/functions/reduceValue.html +215 -0
  124. package/docs/html/functions/removeDustOutputs.html +206 -0
  125. package/docs/html/functions/setReplaceByFee.html +210 -0
  126. package/docs/html/functions/shuffleArray.html +211 -0
  127. package/docs/html/functions/validateAddress.html +216 -0
  128. package/docs/html/functions/validateMnemonic.html +206 -0
  129. package/docs/html/functions/validateTransaction.html +206 -0
  130. package/docs/html/index.html +360 -0
  131. package/docs/html/interfaces/IAddInput.html +231 -0
  132. package/docs/html/interfaces/IAddress.html +247 -0
  133. package/docs/html/interfaces/IAddressData.html +231 -0
  134. package/docs/html/interfaces/IAddressType.html +199 -0
  135. package/docs/html/interfaces/IAddressTypeData.html +252 -0
  136. package/docs/html/interfaces/IAddresses.html +199 -0
  137. package/docs/html/interfaces/IBoostedTransaction.html +238 -0
  138. package/docs/html/interfaces/IBoostedTransactions.html +199 -0
  139. package/docs/html/interfaces/ICreateTransaction.html +224 -0
  140. package/docs/html/interfaces/ICustomGetAddress.html +231 -0
  141. package/docs/html/interfaces/ICustomGetScriptHash.html +224 -0
  142. package/docs/html/interfaces/IElectrumGetAddressBalanceRes.html +235 -0
  143. package/docs/html/interfaces/IExchangeRates.html +210 -0
  144. package/docs/html/interfaces/IFormattedPeerData.html +245 -0
  145. package/docs/html/interfaces/IFormattedTransaction.html +343 -0
  146. package/docs/html/interfaces/IFormattedTransactions.html +199 -0
  147. package/docs/html/interfaces/IGenerateAddresses.html +252 -0
  148. package/docs/html/interfaces/IGenerateAddressesResponse.html +224 -0
  149. package/docs/html/interfaces/IGetAddress.html +231 -0
  150. package/docs/html/interfaces/IGetAddressBalanceRes.html +226 -0
  151. package/docs/html/interfaces/IGetAddressByPath.html +224 -0
  152. package/docs/html/interfaces/IGetAddressHistoryResponse.html +269 -0
  153. package/docs/html/interfaces/IGetAddressResponse.html +231 -0
  154. package/docs/html/interfaces/IGetAddressScriptHashesHistoryResponse.html +245 -0
  155. package/docs/html/interfaces/IGetDerivationPath.html +259 -0
  156. package/docs/html/interfaces/IGetFeeEstimatesResponse.html +238 -0
  157. package/docs/html/interfaces/IGetHeaderResponse.html +245 -0
  158. package/docs/html/interfaces/IGetNextAvailableAddressResponse.html +238 -0
  159. package/docs/html/interfaces/IGetTransactions.html +245 -0
  160. package/docs/html/interfaces/IGetTransactionsFromInputs.html +245 -0
  161. package/docs/html/interfaces/IGetUtxosResponse.html +224 -0
  162. package/docs/html/interfaces/IHeader.html +231 -0
  163. package/docs/html/interfaces/IIndexes.html +238 -0
  164. package/docs/html/interfaces/IKeyDerivationPath.html +247 -0
  165. package/docs/html/interfaces/IKeyDerivationPathData.html +224 -0
  166. package/docs/html/interfaces/INewBlock.html +224 -0
  167. package/docs/html/interfaces/IOnchainFees.html +245 -0
  168. package/docs/html/interfaces/IOutput.html +231 -0
  169. package/docs/html/interfaces/IPeerData.html +231 -0
  170. package/docs/html/interfaces/IRbfData.html +252 -0
  171. package/docs/html/interfaces/ISend.html +224 -0
  172. package/docs/html/interfaces/ISendTransaction.html +322 -0
  173. package/docs/html/interfaces/ISendTx.html +231 -0
  174. package/docs/html/interfaces/ISetupTransaction.html +238 -0
  175. package/docs/html/interfaces/ISubscribeToAddress.html +247 -0
  176. package/docs/html/interfaces/ISubscribeToHeader.html +245 -0
  177. package/docs/html/interfaces/ITargets.html +238 -0
  178. package/docs/html/interfaces/ITransaction.html +281 -0
  179. package/docs/html/interfaces/ITxHash.html +217 -0
  180. package/docs/html/interfaces/ITxHashes.html +235 -0
  181. package/docs/html/interfaces/IUtxo.html +275 -0
  182. package/docs/html/interfaces/IVin.html +252 -0
  183. package/docs/html/interfaces/IVout.html +246 -0
  184. package/docs/html/interfaces/IWallet.html +350 -0
  185. package/docs/html/interfaces/IWalletData.html +343 -0
  186. package/docs/html/types/ElectrumConnectionPubSub.html +233 -0
  187. package/docs/html/types/ElectrumConnectionSubscription.html +204 -0
  188. package/docs/html/types/InputData.html +203 -0
  189. package/docs/html/types/ObjectKeys.html +198 -0
  190. package/docs/html/types/Result.html +201 -0
  191. package/docs/html/types/TAddressIndexInfo.html +204 -0
  192. package/docs/html/types/TAddressLabel.html +193 -0
  193. package/docs/html/types/TAddressType.html +193 -0
  194. package/docs/html/types/TAddressTypeContent.html +198 -0
  195. package/docs/html/types/TAddressTypes.html +193 -0
  196. package/docs/html/types/TAvailableNetworks.html +193 -0
  197. package/docs/html/types/TConnectToElectrumRes.html +193 -0
  198. package/docs/html/types/TDecodeRawTx.html +214 -0
  199. package/docs/html/types/TElectrumNetworks.html +193 -0
  200. package/docs/html/types/TGetAddressHistory.html +200 -0
  201. package/docs/html/types/TGetByteCountInput.html +193 -0
  202. package/docs/html/types/TGetByteCountInputs.html +193 -0
  203. package/docs/html/types/TGetByteCountOutput.html +193 -0
  204. package/docs/html/types/TGetByteCountOutputs.html +193 -0
  205. package/docs/html/types/TGetData.html +211 -0
  206. package/docs/html/types/TGetTotalFeeObj.html +204 -0
  207. package/docs/html/types/TKeyDerivationAccount.html +193 -0
  208. package/docs/html/types/TKeyDerivationChange.html +193 -0
  209. package/docs/html/types/TKeyDerivationCoinType.html +193 -0
  210. package/docs/html/types/TKeyDerivationIndex.html +193 -0
  211. package/docs/html/types/TKeyDerivationPurpose.html +193 -0
  212. package/docs/html/types/TMessageDataMap.html +210 -0
  213. package/docs/html/types/TMessageKeys.html +193 -0
  214. package/docs/html/types/TOnMessage.html +213 -0
  215. package/docs/html/types/TProcessUnconfirmedTransactions.html +202 -0
  216. package/docs/html/types/TProtocol.html +193 -0
  217. package/docs/html/types/TServer.html +204 -0
  218. package/docs/html/types/TSetData.html +213 -0
  219. package/docs/html/types/TSetupTransactionResponse.html +193 -0
  220. package/docs/html/types/TStorage.html +200 -0
  221. package/docs/html/types/TSubscribedReceive.html +193 -0
  222. package/docs/html/types/TTransactionMessage.html +198 -0
  223. package/docs/html/types/TTxResponse.html +206 -0
  224. package/docs/html/types/TTxResult.html +200 -0
  225. package/docs/html/types/TUnspentAddressScriptHashData.html +198 -0
  226. package/docs/html/types/TWalletDataKeys.html +193 -0
  227. package/docs/html/variables/defaultElectrumPorts.html +193 -0
  228. package/docs/html/variables/electrumConnection.html +199 -0
  229. package/docs/html/variables/mostUsedExchangeTickers.html +241 -0
  230. package/docs/markdown/.nojekyll +1 -0
  231. package/docs/markdown/README.md +1875 -0
  232. package/docs/markdown/classes/Electrum.md +718 -0
  233. package/docs/markdown/classes/Transaction.md +536 -0
  234. package/docs/markdown/classes/Wallet.md +2189 -0
  235. package/docs/markdown/enums/EAddressType.md +41 -0
  236. package/docs/markdown/enums/EAvailableNetworks.md +85 -0
  237. package/docs/markdown/enums/EBoostType.md +30 -0
  238. package/docs/markdown/enums/EFeeId.md +63 -0
  239. package/docs/markdown/enums/EPaymentType.md +30 -0
  240. package/docs/markdown/enums/EProtocol.md +30 -0
  241. package/docs/markdown/enums/EUnit.md +41 -0
  242. package/docs/markdown/interfaces/IAddInput.md +41 -0
  243. package/docs/markdown/interfaces/IAddress.md +69 -0
  244. package/docs/markdown/interfaces/IAddressData.md +41 -0
  245. package/docs/markdown/interfaces/IAddressType.md +7 -0
  246. package/docs/markdown/interfaces/IAddressTypeData.md +74 -0
  247. package/docs/markdown/interfaces/IAddresses.md +7 -0
  248. package/docs/markdown/interfaces/IBoostedTransaction.md +52 -0
  249. package/docs/markdown/interfaces/IBoostedTransactions.md +7 -0
  250. package/docs/markdown/interfaces/ICreateTransaction.md +30 -0
  251. package/docs/markdown/interfaces/ICustomGetAddress.md +41 -0
  252. package/docs/markdown/interfaces/ICustomGetScriptHash.md +30 -0
  253. package/docs/markdown/interfaces/IElectrumGetAddressBalanceRes.md +55 -0
  254. package/docs/markdown/interfaces/IExchangeRates.md +7 -0
  255. package/docs/markdown/interfaces/IFormattedPeerData.md +63 -0
  256. package/docs/markdown/interfaces/IFormattedTransaction.md +217 -0
  257. package/docs/markdown/interfaces/IFormattedTransactions.md +7 -0
  258. package/docs/markdown/interfaces/IGenerateAddresses.md +74 -0
  259. package/docs/markdown/interfaces/IGenerateAddressesResponse.md +30 -0
  260. package/docs/markdown/interfaces/IGetAddress.md +41 -0
  261. package/docs/markdown/interfaces/IGetAddressBalanceRes.md +36 -0
  262. package/docs/markdown/interfaces/IGetAddressByPath.md +30 -0
  263. package/docs/markdown/interfaces/IGetAddressHistoryResponse.md +121 -0
  264. package/docs/markdown/interfaces/IGetAddressResponse.md +41 -0
  265. package/docs/markdown/interfaces/IGetAddressScriptHashesHistoryResponse.md +63 -0
  266. package/docs/markdown/interfaces/IGetDerivationPath.md +100 -0
  267. package/docs/markdown/interfaces/IGetFeeEstimatesResponse.md +52 -0
  268. package/docs/markdown/interfaces/IGetHeaderResponse.md +63 -0
  269. package/docs/markdown/interfaces/IGetNextAvailableAddressResponse.md +52 -0
  270. package/docs/markdown/interfaces/IGetTransactions.md +63 -0
  271. package/docs/markdown/interfaces/IGetTransactionsFromInputs.md +63 -0
  272. package/docs/markdown/interfaces/IGetUtxosResponse.md +30 -0
  273. package/docs/markdown/interfaces/IHeader.md +41 -0
  274. package/docs/markdown/interfaces/IIndexes.md +52 -0
  275. package/docs/markdown/interfaces/IKeyDerivationPath.md +69 -0
  276. package/docs/markdown/interfaces/IKeyDerivationPathData.md +30 -0
  277. package/docs/markdown/interfaces/INewBlock.md +30 -0
  278. package/docs/markdown/interfaces/IOnchainFees.md +63 -0
  279. package/docs/markdown/interfaces/IOutput.md +41 -0
  280. package/docs/markdown/interfaces/IPeerData.md +41 -0
  281. package/docs/markdown/interfaces/IRbfData.md +74 -0
  282. package/docs/markdown/interfaces/ISend.md +30 -0
  283. package/docs/markdown/interfaces/ISendTransaction.md +184 -0
  284. package/docs/markdown/interfaces/ISendTx.md +41 -0
  285. package/docs/markdown/interfaces/ISetupTransaction.md +52 -0
  286. package/docs/markdown/interfaces/ISubscribeToAddress.md +60 -0
  287. package/docs/markdown/interfaces/ISubscribeToHeader.md +59 -0
  288. package/docs/markdown/interfaces/ITargets.md +52 -0
  289. package/docs/markdown/interfaces/ITransaction.md +88 -0
  290. package/docs/markdown/interfaces/ITxHash.md +19 -0
  291. package/docs/markdown/interfaces/ITxHashes.md +55 -0
  292. package/docs/markdown/interfaces/IUtxo.md +112 -0
  293. package/docs/markdown/interfaces/IVin.md +70 -0
  294. package/docs/markdown/interfaces/IVout.md +52 -0
  295. package/docs/markdown/interfaces/IWallet.md +209 -0
  296. package/docs/markdown/interfaces/IWalletData.md +217 -0
  297. package/example/helpers.ts +76 -0
  298. package/example/index.ts +77 -0
  299. package/package.json +69 -0
  300. package/src/electrum/constants.ts +28 -0
  301. package/src/electrum/index.ts +838 -0
  302. package/src/index.ts +6 -0
  303. package/src/shapes/electrum.ts +13 -0
  304. package/src/shapes/index.ts +2 -0
  305. package/src/shapes/wallet.ts +133 -0
  306. package/src/transaction/index.ts +1078 -0
  307. package/src/types/electrum.ts +139 -0
  308. package/src/types/index.ts +3 -0
  309. package/src/types/transaction.ts +58 -0
  310. package/src/types/wallet.ts +503 -0
  311. package/src/utils/conversion.ts +88 -0
  312. package/src/utils/derivation-path.ts +171 -0
  313. package/src/utils/electrum.ts +188 -0
  314. package/src/utils/exchange-rate.ts +70 -0
  315. package/src/utils/helpers.ts +191 -0
  316. package/src/utils/index.ts +7 -0
  317. package/src/utils/result.ts +79 -0
  318. package/src/utils/transaction.ts +417 -0
  319. package/src/utils/wallet.ts +351 -0
  320. package/src/wallet/constants.ts +24 -0
  321. package/src/wallet/index.ts +3304 -0
  322. package/tests/constants.ts +9 -0
  323. package/tests/derivation.test.ts +146 -0
  324. package/tests/electrum.test.ts +137 -0
  325. package/tests/storage.test.ts +222 -0
  326. package/tests/transaction.test.ts +187 -0
  327. package/tests/wallet.test.ts +307 -0
  328. package/tsconfig.json +32 -0
  329. package/typedoc.json +5 -0
@@ -0,0 +1,838 @@
1
+ import {
2
+ EAddressType,
3
+ EAvailableNetworks,
4
+ IAddress,
5
+ IAddresses,
6
+ TAddressTypeContent,
7
+ TConnectToElectrumRes,
8
+ IElectrumGetAddressBalanceRes,
9
+ IGetAddressHistoryResponse,
10
+ IGetAddressScriptHashesHistoryResponse,
11
+ IGetHeaderResponse,
12
+ IGetTransactions,
13
+ IGetTransactionsFromInputs,
14
+ IGetUtxosResponse,
15
+ IHeader,
16
+ INewBlock,
17
+ ISubscribeToAddress,
18
+ ISubscribeToHeader,
19
+ ITransaction,
20
+ ITxHash,
21
+ IUtxo,
22
+ TElectrumNetworks,
23
+ TServer,
24
+ TSubscribedReceive,
25
+ TTxResponse,
26
+ TTxResult,
27
+ TUnspentAddressScriptHashData,
28
+ IPeerData,
29
+ TGetAddressHistory,
30
+ TOnMessage
31
+ } from '../types';
32
+ import * as electrum from 'rn-electrum-client/helpers';
33
+ import { err, getAddressFromScriptPubKey, ok, Result } from '../utils';
34
+ import { Wallet } from '../wallet';
35
+ import { CHUNK_LIMIT, GAP_LIMIT } from '../wallet/constants';
36
+ import { getScriptHash, objectKeys } from '../utils';
37
+ import { addressTypes, POLLING_INTERVAL } from '../shapes';
38
+ import { Block } from 'bitcoinjs-lib';
39
+ import { onMessageKeys } from '../shapes';
40
+ import { Server } from 'net';
41
+ import { TLSSocket } from 'tls';
42
+
43
+ let tls, net;
44
+ try {
45
+ tls = require('tls');
46
+ net = require('net');
47
+ } catch {
48
+ // Modules not available, will attempt to use passed instances, if any.
49
+ }
50
+
51
+ export class Electrum {
52
+ private readonly _wallet: Wallet;
53
+ private onMessage: TOnMessage;
54
+ private latestConnectionState: boolean | null = null;
55
+ private connectionPollingInterval: NodeJS.Timeout | null;
56
+ private tls: TLSSocket;
57
+ private net: Server;
58
+
59
+ public servers?: TServer | TServer[];
60
+ public readonly network: EAvailableNetworks;
61
+ public readonly electrumNetwork: TElectrumNetworks;
62
+ public connectedToElectrum: boolean;
63
+ public onReceive?: (data: unknown) => void;
64
+ constructor({
65
+ wallet,
66
+ servers,
67
+ network,
68
+ onReceive,
69
+ tls: _tls,
70
+ net: _net
71
+ }: {
72
+ wallet: Wallet;
73
+ servers?: TServer | TServer[];
74
+ network: EAvailableNetworks;
75
+ onReceive?: (data: unknown) => void;
76
+ tls?: TLSSocket;
77
+ net?: Server;
78
+ }) {
79
+ this._wallet = wallet;
80
+ this.onMessage = wallet?.onMessage ?? ((): null => null);
81
+ this.servers = servers ?? [];
82
+ this.network = network;
83
+ this.electrumNetwork = this.getElectrumNetwork(network);
84
+ this.connectedToElectrum = false;
85
+ this.onReceive = onReceive;
86
+ this.tls = _tls ?? tls;
87
+ this.net = _net ?? net;
88
+ if (!this.tls || !this.net) {
89
+ throw new Error(
90
+ 'TLS and NET modules are not available and were not passed as instances'
91
+ );
92
+ }
93
+ this.connectionPollingInterval = setInterval(
94
+ (): Promise<void> => this.checkConnection(),
95
+ POLLING_INTERVAL
96
+ );
97
+ }
98
+
99
+ public get wallet(): Wallet {
100
+ return this._wallet;
101
+ }
102
+
103
+ async connectToElectrum({
104
+ network = this.network,
105
+ servers
106
+ }: {
107
+ network?: EAvailableNetworks;
108
+ servers?: TServer | TServer[];
109
+ }): Promise<Result<TConnectToElectrumRes>> {
110
+ let customPeers = servers
111
+ ? Array.isArray(servers)
112
+ ? servers
113
+ : [servers]
114
+ : [];
115
+ // @ts-ignore
116
+ customPeers = customPeers.length ? customPeers : this?.servers ?? [];
117
+ const electrumNetwork = this.getElectrumNetwork(network);
118
+ if (electrumNetwork === 'bitcoinRegtest' && !customPeers.length) {
119
+ return err('Regtest requires that you pre-specify a server.');
120
+ }
121
+ const startResponse = await electrum.start({
122
+ network: electrumNetwork,
123
+ tls: this.tls,
124
+ net: this.net,
125
+ customPeers
126
+ });
127
+ if (startResponse.error && !this.wallet.isSwitchingNetworks)
128
+ return err(startResponse.error);
129
+ this.publishConnectionChange(true);
130
+ this.subscribeToHeader().then();
131
+ return ok('Connected to Electrum server.');
132
+ }
133
+
134
+ async isConnected(): Promise<boolean> {
135
+ const { error } = await electrum.pingServer();
136
+ return !error;
137
+ }
138
+
139
+ /**
140
+ * Returns the balance in sats for a given address.
141
+ * @param {string} scriptHash
142
+ * @return {number}
143
+ */
144
+ async getAddressBalance(
145
+ scriptHash: string
146
+ ): Promise<IElectrumGetAddressBalanceRes> {
147
+ if (!this.connectedToElectrum)
148
+ await this.connectToElectrum({
149
+ network: this.network,
150
+ servers: this.servers
151
+ });
152
+ const network = this.electrumNetwork;
153
+ const response = await electrum.getAddressScriptHashBalance({
154
+ scriptHash,
155
+ network
156
+ });
157
+ if (response.error) {
158
+ return { error: response.error, confirmed: 0, unconfirmed: 0 };
159
+ }
160
+ const { confirmed, unconfirmed } = response.data;
161
+ return { error: response.error, confirmed, unconfirmed };
162
+ }
163
+
164
+ async getAddressScriptHashBalances(scriptHashes: string[]): Promise<any> {
165
+ return await electrum.getAddressScriptHashBalances({
166
+ scriptHashes,
167
+ network: this.electrumNetwork
168
+ });
169
+ }
170
+
171
+ /**
172
+ * Returns currently connected peer.
173
+ * @returns {Promise<Result<IPeerData>>}
174
+ */
175
+ async getConnectedPeer(): Promise<Result<IPeerData>> {
176
+ const response = await electrum.getConnectedPeer(this.electrumNetwork);
177
+ if (response?.host && response?.port && response?.protocol) {
178
+ return ok(response);
179
+ }
180
+ return err('No peer available.');
181
+ }
182
+
183
+ /**
184
+ * Returns the network string for use with Electrum methods.
185
+ * @param {EAvailableNetworks} [network]
186
+ * @return {TElectrumNetworks}
187
+ */
188
+ getElectrumNetwork(network: EAvailableNetworks): TElectrumNetworks {
189
+ switch (network) {
190
+ case 'bitcoin':
191
+ return 'bitcoin';
192
+ case 'testnet':
193
+ return 'bitcoinTestnet';
194
+ case 'regtest':
195
+ return 'bitcoinRegtest';
196
+ default:
197
+ return 'bitcoinTestnet';
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Queries Electrum to return the available UTXO's and balance of the provided addresses.
203
+ * @param {EAvailableNetworks} [selectedNetwork]
204
+ * @param {TUnspentAddressScriptHashData} addresses
205
+ */
206
+ async listUnspentAddressScriptHashes({
207
+ addresses
208
+ }: {
209
+ addresses: TUnspentAddressScriptHashData;
210
+ }): Promise<Result<IGetUtxosResponse>> {
211
+ try {
212
+ const unspentAddressResult =
213
+ await electrum.listUnspentAddressScriptHashes({
214
+ scriptHashes: {
215
+ key: 'scriptHash',
216
+ data: addresses
217
+ },
218
+ network: this.electrumNetwork
219
+ });
220
+ if (unspentAddressResult.error) {
221
+ return err(unspentAddressResult.error);
222
+ }
223
+ let balance = 0;
224
+ const utxos: IUtxo[] = [];
225
+ unspentAddressResult.data.map(({ data, result }) => {
226
+ if (result?.length > 0) {
227
+ return result.map((unspentAddress: IUtxo) => {
228
+ balance = balance + unspentAddress.value;
229
+ utxos.push({
230
+ ...data,
231
+ ...unspentAddress
232
+ });
233
+ });
234
+ }
235
+ });
236
+ return ok({ utxos, balance });
237
+ } catch (e) {
238
+ return err(e);
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Returns the available history for the provided address script hashes.
244
+ * @param {IAddress[]} [scriptHashes]
245
+ * @param {boolean} [scanAllAddresses]
246
+ * @returns {Promise<Result<IGetAddressHistoryResponse[]>>}
247
+ */
248
+ async getAddressHistory({
249
+ scriptHashes = [],
250
+ scanAllAddresses = false
251
+ }: {
252
+ scriptHashes?: IAddress[];
253
+ scanAllAddresses?: boolean;
254
+ }): Promise<Result<IGetAddressHistoryResponse[]>> {
255
+ try {
256
+ if (!this.connectedToElectrum)
257
+ await this.connectToElectrum({
258
+ network: this.network,
259
+ servers: this.servers
260
+ });
261
+ const currentWallet = this._wallet.data;
262
+ const currentAddresses: TAddressTypeContent<IAddresses> =
263
+ currentWallet.addresses;
264
+ const currentChangeAddresses: TAddressTypeContent<IAddresses> =
265
+ currentWallet.changeAddresses;
266
+
267
+ const addressIndexes = currentWallet.addressIndex;
268
+ const changeAddressIndexes = currentWallet.changeAddressIndex;
269
+
270
+ if (scriptHashes.length < 1) {
271
+ const addressTypeKeys = objectKeys(addressTypes);
272
+ addressTypeKeys.forEach((addressType) => {
273
+ const addresses = currentAddresses[addressType];
274
+ const changeAddresses = currentChangeAddresses[addressType];
275
+ let addressValues = Object.values(addresses);
276
+ let changeAddressValues = Object.values(changeAddresses);
277
+
278
+ const addressIndex = addressIndexes[addressType].index;
279
+ const changeAddressIndex = changeAddressIndexes[addressType].index;
280
+
281
+ // Instead of scanning all addresses, adhere to the gap limit.
282
+ if (
283
+ !scanAllAddresses &&
284
+ addressIndex >= 0 &&
285
+ changeAddressIndex >= 0
286
+ ) {
287
+ addressValues = addressValues.filter(
288
+ (a) => Math.abs(addressIndex - a.index) <= GAP_LIMIT
289
+ );
290
+ changeAddressValues = changeAddressValues.filter(
291
+ (a) => Math.abs(changeAddressIndex - a.index) <= GAP_LIMIT
292
+ );
293
+ }
294
+
295
+ scriptHashes = [
296
+ ...scriptHashes,
297
+ ...addressValues,
298
+ ...changeAddressValues
299
+ ];
300
+ });
301
+ }
302
+ // remove items with same path
303
+ scriptHashes = scriptHashes.filter((sh, index, arr) => {
304
+ return index === arr.findIndex((v) => sh.path === v.path);
305
+ });
306
+ if (scriptHashes.length < 1) {
307
+ return err('No scriptHashes available to check.');
308
+ }
309
+
310
+ const combinedResponse: TTxResponse[] = [];
311
+
312
+ // split payload in chunks of 10 addresses per-request
313
+ for (let i = 0; i < scriptHashes.length; i += CHUNK_LIMIT) {
314
+ const chunk = scriptHashes.slice(i, i + CHUNK_LIMIT);
315
+ const payload = {
316
+ key: 'scriptHash',
317
+ data: chunk
318
+ };
319
+
320
+ const response: IGetAddressScriptHashesHistoryResponse =
321
+ await electrum.getAddressScriptHashesHistory({
322
+ scriptHashes: payload,
323
+ network: this.electrumNetwork
324
+ });
325
+
326
+ const mempoolResponse: IGetAddressScriptHashesHistoryResponse =
327
+ await electrum.getAddressScriptHashesMempool({
328
+ scriptHashes: payload,
329
+ network: this.electrumNetwork
330
+ });
331
+
332
+ if (response.error || mempoolResponse.error) {
333
+ return err('Unable to get address history.');
334
+ }
335
+ combinedResponse.push(...response.data, ...mempoolResponse.data);
336
+ }
337
+
338
+ const history: IGetAddressHistoryResponse[] = [];
339
+ combinedResponse.forEach(
340
+ ({ data, result }: { data: IAddress; result: TTxResult[] }): void => {
341
+ if (result && result?.length > 0) {
342
+ result.forEach((item) => {
343
+ history.push({ ...data, ...item });
344
+ });
345
+ }
346
+ }
347
+ );
348
+ return ok(history);
349
+ } catch (e) {
350
+ return err(e);
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Used to retrieve scriptPubkey history for LDK.
356
+ * @param {string} scriptPubkey
357
+ * @returns {Promise<TGetAddressHistory[]>}
358
+ */
359
+ async getScriptPubKeyHistory(
360
+ scriptPubkey: string
361
+ ): Promise<TGetAddressHistory[]> {
362
+ const history: { txid: string; height: number }[] = [];
363
+ const address = getAddressFromScriptPubKey(scriptPubkey, this.network);
364
+ if (!address) {
365
+ return history;
366
+ }
367
+ const scriptHash = getScriptHash({
368
+ network: this.network,
369
+ address
370
+ });
371
+ if (!scriptHash) {
372
+ return history;
373
+ }
374
+ const response = await electrum.getAddressScriptHashesHistory({
375
+ scriptHashes: [scriptHash],
376
+ network: this.electrumNetwork
377
+ });
378
+ if (response.error) {
379
+ return history;
380
+ }
381
+ await Promise.all(
382
+ response.data.map(({ result }): void => {
383
+ if (result && result?.length > 0) {
384
+ result.map((item) => {
385
+ history.push({
386
+ txid: item?.tx_hash ?? '',
387
+ height: item?.height ?? 0
388
+ });
389
+ });
390
+ }
391
+ })
392
+ );
393
+ return history;
394
+ }
395
+
396
+ /**
397
+ * Returns UTXO's for a given wallet and network along with the available balance.
398
+ * @param {boolean} [scanAllAddresses]
399
+ * @returns {Promise<Result<IGetUtxosResponse>>}
400
+ */
401
+ async getUtxos({
402
+ scanAllAddresses = false
403
+ }: {
404
+ scanAllAddresses?: boolean;
405
+ }): Promise<Result<IGetUtxosResponse>> {
406
+ try {
407
+ if (!this.connectedToElectrum)
408
+ await this.connectToElectrum({
409
+ network: this.network,
410
+ servers: this.servers
411
+ });
412
+ const currentWallet = this._wallet.data;
413
+
414
+ const addressTypeKeys = Object.values(EAddressType);
415
+ let addresses = {} as IAddresses;
416
+ let changeAddresses = {} as IAddresses;
417
+ const existingUtxos: { [key: string]: IUtxo } = {};
418
+
419
+ for (const addressType of addressTypeKeys) {
420
+ const addressCount = Object.keys(currentWallet.addresses[addressType])
421
+ ?.length;
422
+
423
+ // Check if addresses of this type have been generated. If not, skip.
424
+ if (addressCount <= 0) {
425
+ break;
426
+ }
427
+
428
+ // Grab the current index for both addresses and change addresses.
429
+ const addressIndex = currentWallet.addressIndex[addressType].index;
430
+ const changeAddressIndex =
431
+ currentWallet.changeAddressIndex[addressType].index;
432
+
433
+ // Grab all addresses and change addresses.
434
+ const allAddresses = currentWallet.addresses[addressType];
435
+ const allChangeAddresses = currentWallet.changeAddresses[addressType];
436
+
437
+ // Instead of scanning all addresses, adhere to the gap limit.
438
+ if (!scanAllAddresses && addressIndex >= 0 && changeAddressIndex >= 0) {
439
+ Object.values(allAddresses).map((a) => {
440
+ if (Math.abs(a.index - addressIndex) <= GAP_LIMIT) {
441
+ addresses[a.scriptHash] = a;
442
+ }
443
+ });
444
+ Object.values(allChangeAddresses).map((a) => {
445
+ if (Math.abs(a.index - changeAddressIndex) <= GAP_LIMIT) {
446
+ changeAddresses[a.scriptHash] = a;
447
+ }
448
+ });
449
+ } else {
450
+ addresses = { ...addresses, ...allAddresses };
451
+ changeAddresses = { ...changeAddresses, ...allChangeAddresses };
452
+ }
453
+ }
454
+
455
+ // Make sure we're re-check existing utxos that may exist outside the gap limit and putting them in the necessary format.
456
+ currentWallet.utxos.map((utxo) => {
457
+ existingUtxos[utxo.scriptHash] = utxo;
458
+ });
459
+
460
+ const data: TUnspentAddressScriptHashData = {
461
+ ...addresses,
462
+ ...changeAddresses,
463
+ ...existingUtxos
464
+ };
465
+
466
+ return this.listUnspentAddressScriptHashes({ addresses: data });
467
+ } catch (e) {
468
+ return err(e);
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Returns available transactions from electrum based on the provided txHashes.
474
+ * @param {ITxHash[]} txHashes
475
+ * @return {Promise<Result<IGetTransactions>>}
476
+ */
477
+ async getTransactions({
478
+ txHashes = []
479
+ }: {
480
+ txHashes: ITxHash[];
481
+ }): Promise<Result<IGetTransactions>> {
482
+ try {
483
+ if (txHashes.length < 1) {
484
+ return ok({
485
+ error: false,
486
+ id: 0,
487
+ method: 'getTransactions',
488
+ network: this.electrumNetwork,
489
+ data: []
490
+ });
491
+ }
492
+
493
+ const result: ITransaction<IUtxo>[] = [];
494
+
495
+ // split payload in chunks of 10 transactions per-request
496
+ for (let i = 0; i < txHashes.length; i += CHUNK_LIMIT) {
497
+ const chunk = txHashes.slice(i, i + CHUNK_LIMIT);
498
+
499
+ const data = {
500
+ key: 'tx_hash',
501
+ data: chunk
502
+ };
503
+ const response = await electrum.getTransactions({
504
+ txHashes: data,
505
+ network: this.electrumNetwork
506
+ });
507
+ if (response.error) {
508
+ return err(response);
509
+ }
510
+ result.push(...response.data);
511
+ }
512
+ return ok({
513
+ error: false,
514
+ id: 0,
515
+ method: 'getTransactions',
516
+ network: this.electrumNetwork,
517
+ data: result
518
+ });
519
+ } catch (e) {
520
+ return err(e);
521
+ }
522
+ }
523
+
524
+ /**
525
+ * Determines whether a transaction exists based on the transaction response from electrum.
526
+ * @param {ITransaction<IUtxo>} txData
527
+ * @returns {boolean}
528
+ */
529
+ public transactionExists(txData: ITransaction<IUtxo>): boolean {
530
+ if (
531
+ // @ts-ignore
532
+ txData?.error &&
533
+ // @ts-ignore
534
+ txData?.error?.message &&
535
+ /No such mempool or blockchain transaction|Invalid tx hash/.test(
536
+ // @ts-ignore
537
+ txData?.error?.message
538
+ )
539
+ ) {
540
+ //Transaction was removed/bumped from the mempool or potentially reorg'd out.
541
+ return false;
542
+ }
543
+ return true;
544
+ }
545
+
546
+ /**
547
+ * Returns the block hex of the provided block height.
548
+ * @param {number} [height]
549
+ * @param {TAvailableNetworks} [selectedNetwork]
550
+ * @returns {Promise<Result<string>>}
551
+ */
552
+ public async getBlockHex({
553
+ height = 0
554
+ }: {
555
+ height?: number;
556
+ }): Promise<Result<string>> {
557
+ const response: IGetHeaderResponse = await electrum.getHeader({
558
+ height,
559
+ network: this.electrumNetwork
560
+ });
561
+ if (response.error) {
562
+ return err(response.data);
563
+ }
564
+ return ok(response.data);
565
+ }
566
+
567
+ /**
568
+ * Returns the block hash given a block hex.
569
+ * Leaving blockHex empty will return the last known block hash from storage.
570
+ * @param {string} [blockHex]
571
+ * @param {TAvailableNetworks} [selectedNetwork]
572
+ * @returns {string}
573
+ */
574
+ public getBlockHashFromHex({ blockHex }: { blockHex?: string }): string {
575
+ // If empty, return the last known block hex from storage.
576
+ if (!blockHex) {
577
+ const { hex } = this.getBlockHeader();
578
+ blockHex = hex;
579
+ }
580
+ if (!blockHex) return '';
581
+ const block = Block.fromHex(blockHex);
582
+ const hash = block.getId();
583
+ return hash;
584
+ }
585
+
586
+ /**
587
+ * Returns last known block height, and it's corresponding hex from local storage.
588
+ * @returns {IHeader}
589
+ */
590
+ public getBlockHeader(): IHeader {
591
+ return this.wallet.data.header;
592
+ }
593
+
594
+ /**
595
+ * Returns transactions associated with the provided transaction hashes.
596
+ * @param {ITxHash[]} txHashes
597
+ * @return {Promise<Result<IGetTransactionsFromInputs>>}
598
+ */
599
+ async getTransactionsFromInputs({
600
+ txHashes = []
601
+ }: {
602
+ txHashes: ITxHash[];
603
+ }): Promise<Result<IGetTransactionsFromInputs>> {
604
+ try {
605
+ const data = {
606
+ key: 'tx_hash',
607
+ data: txHashes
608
+ };
609
+ const response = await electrum.getTransactions({
610
+ txHashes: data,
611
+ network: this.electrumNetwork
612
+ });
613
+ if (!response.error) {
614
+ return ok(response);
615
+ } else {
616
+ return err(response);
617
+ }
618
+ } catch (e) {
619
+ return err(e);
620
+ }
621
+ }
622
+
623
+ /**
624
+ * Returns the merkle branch to a confirmed transaction given its hash and height.
625
+ * @param {string} tx_hash
626
+ * @param {number} height
627
+ * @returns {Promise<{ merkle: string[]; block_height: number; pos: number }>}
628
+ */
629
+ async getTransactionMerkle({
630
+ tx_hash,
631
+ height
632
+ }: {
633
+ tx_hash: string;
634
+ height: number;
635
+ }): Promise<{
636
+ merkle: string[];
637
+ block_height: number;
638
+ pos: number;
639
+ }> {
640
+ return await electrum.getTransactionMerkle({
641
+ tx_hash,
642
+ height,
643
+ network: this.electrumNetwork
644
+ });
645
+ }
646
+
647
+ /**
648
+ * Subscribes to the current networks headers.
649
+ * @return {Promise<Result<string>>}
650
+ */
651
+ public async subscribeToHeader(): Promise<Result<IHeader>> {
652
+ const subscribeResponse: ISubscribeToHeader =
653
+ await electrum.subscribeHeader({
654
+ network: this.electrumNetwork,
655
+ onReceive: (data: INewBlock[]) => {
656
+ const hex = data[0].hex;
657
+ const hash = this.getBlockHashFromHex({ blockHex: hex });
658
+ const header: IHeader = { ...data[0], hash };
659
+ this._wallet.updateHeader(header);
660
+ this.onReceive?.(data);
661
+ this.onMessage(onMessageKeys.newBlock, data[0]);
662
+ }
663
+ });
664
+ if (subscribeResponse.error) {
665
+ return err('Unable to subscribe to headers.');
666
+ }
667
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
668
+ // @ts-ignore
669
+ if (subscribeResponse?.data === 'Already Subscribed.') {
670
+ return ok(this.getBlockHeader());
671
+ }
672
+ // Update local storage with current height and hex.
673
+ const hex = subscribeResponse.data.hex;
674
+ const hash = this.getBlockHashFromHex({ blockHex: hex });
675
+ const header = { ...subscribeResponse.data, hash };
676
+ await this._wallet.updateHeader(header);
677
+ return ok(header);
678
+ }
679
+
680
+ /**
681
+ * Subscribes to a number of address script hashes for receiving.
682
+ * @param {string[]} scriptHashes
683
+ * @param onReceive
684
+ * @return {Promise<Result<string>>}
685
+ */
686
+ async subscribeToAddresses({
687
+ scriptHashes = [],
688
+ onReceive
689
+ }: {
690
+ scriptHashes?: string[];
691
+ onReceive?: (data: TSubscribedReceive) => void;
692
+ } = {}): Promise<Result<string>> {
693
+ const currentWallet = this._wallet.data;
694
+ const addressTypeKeys = objectKeys(addressTypes);
695
+ // Gather the receiving address scripthash for each address type if no scripthashes were provided.
696
+ if (!scriptHashes.length) {
697
+ for (const addressType of addressTypeKeys) {
698
+ const addresses = currentWallet.addresses[addressType];
699
+ const addressCount = Object.keys(addresses).length;
700
+
701
+ // Check if addresses of this type have been generated. If not, skip.
702
+ if (addressCount > 0) {
703
+ let addressIndex = currentWallet.addressIndex[addressType]?.index;
704
+ addressIndex = addressIndex > 0 ? addressIndex : 0;
705
+
706
+ // Only subscribe up to the gap limit.
707
+ const addressesInRange = Object.values(addresses).filter(
708
+ (address) => Math.abs(address.index - addressIndex) <= GAP_LIMIT
709
+ );
710
+ const addressesToSubscribe = addressesInRange.slice(-GAP_LIMIT);
711
+ const addressScriptHashes = addressesToSubscribe.map(
712
+ ({ scriptHash }) => scriptHash
713
+ );
714
+ scriptHashes.push(...addressScriptHashes);
715
+ }
716
+ }
717
+ }
718
+
719
+ // Subscribe to all provided script hashes.
720
+ const promises = scriptHashes.map(async (scriptHash) => {
721
+ const response: ISubscribeToAddress = await electrum.subscribeAddress({
722
+ scriptHash,
723
+ network: this.electrumNetwork,
724
+ onReceive: async (data: TSubscribedReceive): Promise<void> => {
725
+ onReceive?.(data);
726
+ this._wallet.refreshWallet({});
727
+ }
728
+ });
729
+ if (response.error) {
730
+ throw Error('Unable to subscribe to receiving addresses.');
731
+ }
732
+ });
733
+
734
+ try {
735
+ await Promise.all(promises);
736
+ } catch (e) {
737
+ return err(e);
738
+ }
739
+
740
+ return ok('Successfully subscribed to addresses.');
741
+ }
742
+
743
+ public async broadcastTransaction({
744
+ rawTx,
745
+ subscribeToOutputAddress = true
746
+ }: {
747
+ rawTx: string;
748
+ subscribeToOutputAddress?: boolean;
749
+ }): Promise<Result<string>> {
750
+ /**
751
+ * Subscribe to the output address and refresh the wallet when the Electrum server detects it.
752
+ * This prevents updating the wallet prior to the Electrum server detecting the new tx in the mempool.
753
+ */
754
+ if (subscribeToOutputAddress) {
755
+ const transaction = this._wallet.transaction.data;
756
+ for (const o of transaction.outputs) {
757
+ const address = o?.address;
758
+ if (address) {
759
+ const scriptHash = getScriptHash({ address, network: this.network });
760
+ if (scriptHash) {
761
+ await this.subscribeToAddresses({
762
+ scriptHashes: [scriptHash]
763
+ });
764
+ }
765
+ }
766
+ }
767
+ }
768
+
769
+ const broadcastResponse = await electrum.broadcastTransaction({
770
+ rawTx,
771
+ network: this.electrumNetwork
772
+ });
773
+ // TODO: This needs to be resolved in rn-electrum-client
774
+ if (broadcastResponse.error || broadcastResponse.data.includes(' ')) {
775
+ return err(broadcastResponse.data);
776
+ }
777
+ return ok(broadcastResponse.data);
778
+ }
779
+
780
+ /**
781
+ * Attempts to check the current Electrum connection.
782
+ * @private
783
+ * @returns {Promise<void>}
784
+ */
785
+ private async checkConnection(): Promise<void> {
786
+ try {
787
+ const { error } = await electrum.pingServer();
788
+
789
+ if (error) {
790
+ console.log('Connection to Electrum Server lost, reconnecting...');
791
+ const response = await this.connectToElectrum({
792
+ network: this.network,
793
+ servers: this.servers
794
+ });
795
+
796
+ if (response.isErr()) {
797
+ this.publishConnectionChange(false);
798
+ }
799
+ } else {
800
+ this.publishConnectionChange(true);
801
+ }
802
+ } catch (e) {
803
+ console.error(e);
804
+ this.publishConnectionChange(false);
805
+ }
806
+ }
807
+
808
+ private publishConnectionChange(isConnected: boolean): void {
809
+ if (
810
+ this.latestConnectionState !== isConnected &&
811
+ !this.wallet.isSwitchingNetworks
812
+ ) {
813
+ this.onMessage('connectedToElectrum', isConnected);
814
+ this.connectedToElectrum = isConnected;
815
+ this.latestConnectionState = isConnected;
816
+ }
817
+ }
818
+
819
+ public async disconnect(): Promise<void> {
820
+ this.stopConnectionPolling();
821
+ await electrum.stop();
822
+ }
823
+
824
+ public startConnectionPolling(): void {
825
+ if (this.connectionPollingInterval) return;
826
+ this.connectionPollingInterval = setInterval(
827
+ (): Promise<void> => this.checkConnection(),
828
+ POLLING_INTERVAL
829
+ );
830
+ }
831
+
832
+ public stopConnectionPolling(): void {
833
+ if (this.connectionPollingInterval) {
834
+ clearInterval(this.connectionPollingInterval);
835
+ this.connectionPollingInterval = null;
836
+ }
837
+ }
838
+ }