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,88 @@
1
+ import { default as bitcoinUnits } from 'bitcoin-units';
2
+ import { EUnit } from '../types';
3
+
4
+ /**
5
+ * Converts a value in BTC to satoshis
6
+ * @param {number} value
7
+ * @returns {number}
8
+ */
9
+ export const btcToSats = (value: number): number => {
10
+ try {
11
+ return Number(bitcoinUnits(value, 'BTC').to('satoshi').value().toFixed(0));
12
+ } catch {
13
+ return 0;
14
+ }
15
+ };
16
+
17
+ /**
18
+ * Converts a value in satoshis to BTC
19
+ * @param {number} value
20
+ * @returns {number}
21
+ */
22
+ export const satsToBtc = (value: number): number => {
23
+ return bitcoinUnits(value, 'sats').to('BTC').value();
24
+ };
25
+
26
+ /**
27
+ * Converts an amount of currency in a specific unit to satoshis
28
+ * @param {number} value
29
+ * @param {EUnit} unit
30
+ * @param {number} exchangeRate
31
+ * @param {string} currency
32
+ */
33
+ export const convertToSats = (
34
+ value: number | string,
35
+ unit: EUnit,
36
+ exchangeRate: number,
37
+ currency = 'EUR'
38
+ ): number => {
39
+ const amount = Number(value);
40
+
41
+ if (unit === EUnit.BTC) {
42
+ return btcToSats(amount);
43
+ }
44
+
45
+ if (unit === EUnit.fiat) {
46
+ return fiatToBitcoinUnit({
47
+ fiatValue: amount,
48
+ unit: EUnit.satoshi,
49
+ exchangeRate,
50
+ currency
51
+ });
52
+ }
53
+
54
+ return amount;
55
+ };
56
+
57
+ /**
58
+ * Converts a fiat value to a bitcoin unit.
59
+ * @param {string | number} fiatValue
60
+ * @param {number} exchangeRate
61
+ * @param {string} currency
62
+ * @param {EUnit} unit
63
+ * @returns {number}
64
+ */
65
+ export const fiatToBitcoinUnit = ({
66
+ fiatValue,
67
+ exchangeRate,
68
+ currency,
69
+ unit
70
+ }: {
71
+ fiatValue: string | number;
72
+ exchangeRate: number;
73
+ currency: string;
74
+ unit: EUnit;
75
+ }): number => {
76
+ try {
77
+ // this throws if exchangeRate is 0
78
+ bitcoinUnits.setFiat(currency, exchangeRate);
79
+ const value = bitcoinUnits(Number(fiatValue), currency)
80
+ .to(unit)
81
+ .value()
82
+ .toFixed(unit === EUnit.satoshi ? 0 : 8); // satoshi cannot be a fractional number
83
+
84
+ return Number(value);
85
+ } catch {
86
+ return 0;
87
+ }
88
+ };
@@ -0,0 +1,171 @@
1
+ import {
2
+ EAddressType,
3
+ EAvailableNetworks,
4
+ IKeyDerivationPath,
5
+ TKeyDerivationAccount,
6
+ TKeyDerivationChange,
7
+ TKeyDerivationCoinType,
8
+ TKeyDerivationPurpose
9
+ } from '../types';
10
+ import { addressTypes } from '../shapes';
11
+ import { err, ok, Result } from './result';
12
+
13
+ /**
14
+ * Parses a key derivation path in string format Ex: "m/84'/0'/0'/0/0" and returns IKeyDerivationPath.
15
+ * @param {string} keyDerivationPath
16
+ * @param {TKeyDerivationPurpose | string} [purpose]
17
+ * @param {boolean} [changeAddress]
18
+ * @param {string} [index]
19
+ * @param {TAvailableNetworks} [network]
20
+ * @returns {Result<IKeyDerivationPath>}
21
+ */
22
+ export const getKeyDerivationPathObject = ({
23
+ path = '',
24
+ purpose,
25
+ changeAddress,
26
+ index,
27
+ network
28
+ }: {
29
+ path: string;
30
+ purpose?: TKeyDerivationPurpose;
31
+ changeAddress?: boolean;
32
+ index?: string;
33
+ network: EAvailableNetworks;
34
+ }): Result<IKeyDerivationPath> => {
35
+ try {
36
+ const parsedPath = path.replace(/'/g, '').split('/');
37
+
38
+ if (!purpose) {
39
+ purpose = parsedPath[1] as TKeyDerivationPurpose;
40
+ }
41
+
42
+ let coinType = parsedPath[2] as TKeyDerivationCoinType;
43
+ if (network) {
44
+ coinType =
45
+ network.toLocaleLowerCase() === EAvailableNetworks.bitcoin ? '0' : '1';
46
+ }
47
+
48
+ const account = parsedPath[3] as TKeyDerivationAccount;
49
+
50
+ let change = parsedPath[4] as TKeyDerivationChange;
51
+ if (changeAddress !== undefined) {
52
+ change = changeAddress ? '1' : '0';
53
+ }
54
+
55
+ if (!index) {
56
+ index = parsedPath[5];
57
+ }
58
+
59
+ return ok({
60
+ purpose,
61
+ coinType,
62
+ account,
63
+ change,
64
+ index
65
+ });
66
+ } catch (e) {
67
+ return err(e);
68
+ }
69
+ };
70
+
71
+ /**
72
+ * Parses a key derivation path object and returns it in string format. Ex: "m/84'/0'/0'/0/0"
73
+ * @param {IKeyDerivationPath} path
74
+ * @param {TKeyDerivationPurpose | string} [purpose]
75
+ * @param {boolean} [changeAddress]
76
+ * @param {number} [accountType]
77
+ * @param {string} [addressIndex]
78
+ * @returns {Result<string>}
79
+ */
80
+ export const getKeyDerivationPathString = ({
81
+ addressType = EAddressType.p2wpkh,
82
+ path,
83
+ purpose,
84
+ accountType,
85
+ changeAddress = false,
86
+ index = '0',
87
+ network
88
+ }: {
89
+ addressType: EAddressType;
90
+ path?: IKeyDerivationPath;
91
+ purpose?: TKeyDerivationPurpose;
92
+ accountType?: string | number;
93
+ changeAddress?: boolean;
94
+ index?: string | number;
95
+ network: EAvailableNetworks;
96
+ }): Result<string> => {
97
+ try {
98
+ if (!path) {
99
+ // Get default path object for the network and set it from there.
100
+ const str = addressTypes[addressType].path;
101
+ const res = getKeyDerivationPathObject({ path: str, network });
102
+ if (res.isErr()) {
103
+ return err(res.error.message);
104
+ }
105
+ path = res.value;
106
+ }
107
+ //Specifically specifying purpose will override the default accountType purpose value.
108
+ if (purpose !== undefined) {
109
+ path.purpose = purpose;
110
+ }
111
+
112
+ path.coinType =
113
+ network.toLocaleLowerCase() === EAvailableNetworks.bitcoin ? '0' : '1';
114
+
115
+ if (accountType !== undefined) {
116
+ if (typeof accountType === 'number') {
117
+ path.account = String(accountType);
118
+ }
119
+ path.account =
120
+ typeof accountType === 'number' ? String(accountType) : accountType;
121
+ } else {
122
+ path.account = '0';
123
+ }
124
+
125
+ path.change = changeAddress ? '1' : '0';
126
+
127
+ if (!index) {
128
+ index = '0';
129
+ }
130
+ if (typeof index === 'number') {
131
+ index = String(index);
132
+ }
133
+
134
+ return ok(
135
+ `m/${path.purpose}'/${path.coinType}'/${path.account}'/${path.change}/${index}`
136
+ );
137
+ } catch (e) {
138
+ return err(e);
139
+ }
140
+ };
141
+
142
+ /**
143
+ * Returns the address type from the specified derivation path.
144
+ * @param {string | IKeyDerivationPath} path
145
+ * @returns {Result<EAddressType>}
146
+ */
147
+ export const getAddressTypeFromPath = (
148
+ path: string | IKeyDerivationPath
149
+ ): Result<EAddressType> => {
150
+ try {
151
+ let purpose;
152
+ if (typeof path === 'object') {
153
+ purpose = path.purpose;
154
+ } else if (typeof path === 'string') {
155
+ const parsedPathString = path.replace(/'/g, '').split('/');
156
+ purpose = parsedPathString[1];
157
+ }
158
+ switch (purpose) {
159
+ case '44':
160
+ return ok(EAddressType.p2pkh);
161
+ case '49':
162
+ return ok(EAddressType.p2sh);
163
+ case '84':
164
+ return ok(EAddressType.p2wpkh);
165
+ default:
166
+ return err('Invalid path');
167
+ }
168
+ } catch (e) {
169
+ return err(e);
170
+ }
171
+ };
@@ -0,0 +1,188 @@
1
+ import * as electrum from 'rn-electrum-client/helpers';
2
+ import { err, ok, Result } from './result';
3
+
4
+ import {
5
+ EAvailableNetworks,
6
+ ElectrumConnectionPubSub,
7
+ ElectrumConnectionSubscription,
8
+ IFormattedPeerData,
9
+ TProtocol
10
+ } from '../types';
11
+ import * as hardcodedPeers from 'rn-electrum-client/helpers/peers.json';
12
+
13
+ const POLLING_INTERVAL = 1000 * 20;
14
+ export const defaultElectrumPorts = ['51002', '50002', '51001', '50001'];
15
+
16
+ /**
17
+ * Returns the default port for the given network and protocol.
18
+ * @param {EAvailableNetworks} [selectedNetwork]
19
+ * @param {string} [protocol]
20
+ * @returns {number}
21
+ */
22
+ export const getDefaultPort = (
23
+ selectedNetwork: EAvailableNetworks,
24
+ protocol: TProtocol
25
+ ): number => {
26
+ if (protocol === 'ssl') {
27
+ return selectedNetwork === 'testnet' ? 51002 : 50002;
28
+ } else {
29
+ return selectedNetwork === 'testnet' ? 51001 : 50001;
30
+ }
31
+ };
32
+
33
+ /**
34
+ * Returns the protocol for the given network and default port.
35
+ * @param {string} [port]
36
+ * @param {EAvailableNetworks} [network]
37
+ * @returns {TProtocol | undefined}
38
+ */
39
+ export const getProtocolForPort = (
40
+ port: string,
41
+ network: EAvailableNetworks
42
+ ): TProtocol | undefined => {
43
+ if (port === '443') {
44
+ return 'ssl';
45
+ }
46
+
47
+ if (network === 'testnet') {
48
+ return port === '51002' ? 'ssl' : 'tcp';
49
+ }
50
+
51
+ return port === '50002' ? 'ssl' : 'tcp';
52
+ };
53
+
54
+ /**
55
+ * Formats the peer data response from an Electrum server.
56
+ * @param {[string, string, [string, string, string]]} data
57
+ * @returns Result<IFormattedPeerData>
58
+ */
59
+ export const formatPeerData = (
60
+ data: [string, string, [string, string, string]]
61
+ ): Result<IFormattedPeerData> => {
62
+ try {
63
+ if (!data) {
64
+ return err('No data provided.');
65
+ }
66
+ if (data?.length !== 3) {
67
+ return err('Invalid peer data');
68
+ }
69
+ if (data[2]?.length < 2) {
70
+ return err('Invalid peer data');
71
+ }
72
+ const [ip, host, ports] = data;
73
+ const [version, ssl, tcp] = ports;
74
+ return ok({
75
+ ip,
76
+ host,
77
+ version,
78
+ ssl,
79
+ tcp
80
+ });
81
+ } catch (e) {
82
+ if (typeof e === 'string' || e instanceof Error) {
83
+ return err(e);
84
+ }
85
+ return err('Unable to format peer data.');
86
+ }
87
+ };
88
+
89
+ /**
90
+ * Returns an array of peers.
91
+ * If unable to acquire peers from an Electrum server the method will default to the hardcoded peers in peers.json.
92
+ * @param {EAvailableNetworks} [selectedNetwork]
93
+ * @returns Promise<Result<IFormattedPeerData[]>>
94
+ */
95
+ export const getPeers = async ({
96
+ selectedNetwork
97
+ }: {
98
+ selectedNetwork: EAvailableNetworks;
99
+ }): Promise<Result<IFormattedPeerData[]>> => {
100
+ try {
101
+ const response = await electrum.getPeers({ network: selectedNetwork });
102
+ if (!response.error) {
103
+ // Return an array of peers provided by the currently connected electrum server.
104
+ const peers: IFormattedPeerData[] = [];
105
+ await Promise.all(
106
+ response.data.map(async (peer) => {
107
+ const formattedPeer = await formatPeerData(peer);
108
+ if (formattedPeer.isOk()) {
109
+ peers.push(formattedPeer.value);
110
+ }
111
+ })
112
+ );
113
+ if (peers?.length > 0) {
114
+ return ok(peers);
115
+ }
116
+ }
117
+ // No peers available grab hardcoded peers instead.
118
+ return ok(hardcodedPeers[selectedNetwork]);
119
+ } catch (e) {
120
+ if (typeof e === 'string' || e instanceof Error) {
121
+ return err(e);
122
+ }
123
+ return err('Unable to get peers.');
124
+ }
125
+ };
126
+
127
+ /**
128
+ * Background task that checks the connection to the Electrum server with a PubSub
129
+ * If connection was lost this will try to reconnect in the specified interval
130
+ * @param {() => Result<null>} [connectToElectrum]
131
+ * @returns {ElectrumConnectionPubSub}
132
+ */
133
+ export const electrumConnection = ((
134
+ connectToElectrum?: () => Result<null>
135
+ ): ElectrumConnectionPubSub => {
136
+ const subscribers: Set<(isConnected: boolean) => void> = new Set();
137
+ let latestState: boolean | null = null;
138
+
139
+ setInterval(async () => {
140
+ try {
141
+ const { error } = await electrum.pingServer();
142
+
143
+ if (error) {
144
+ if (connectToElectrum) {
145
+ console.log('Connection to Electrum Server lost, reconnecting...');
146
+ const response = await connectToElectrum();
147
+
148
+ if (response.isErr()) {
149
+ electrumConnection.publish(false);
150
+ }
151
+ }
152
+ } else {
153
+ electrumConnection.publish(true);
154
+ }
155
+ } catch (e) {
156
+ console.error(e);
157
+ }
158
+ }, POLLING_INTERVAL);
159
+
160
+ const publish = (isConnected: boolean): void => {
161
+ // Skip if no subscribers
162
+ if (subscribers.size === 0) {
163
+ return;
164
+ }
165
+
166
+ // Skip if state hasn't changed
167
+ if (latestState === isConnected) {
168
+ return;
169
+ }
170
+
171
+ latestState = isConnected;
172
+ subscribers.forEach((callback) => callback(isConnected));
173
+ };
174
+
175
+ const subscribe = (
176
+ callback: (isConnected: boolean) => void
177
+ ): ElectrumConnectionSubscription => {
178
+ subscribers.add(callback);
179
+
180
+ return {
181
+ remove: (): void => {
182
+ subscribers.delete(callback);
183
+ }
184
+ };
185
+ };
186
+
187
+ return { publish, subscribe };
188
+ })();
@@ -0,0 +1,70 @@
1
+ import { ok, err, Result } from './result';
2
+ import { BLOCKTANK_HOST } from '../wallet/constants';
3
+ import { IExchangeRates } from '../types';
4
+
5
+ export const mostUsedExchangeTickers = {
6
+ USD: {
7
+ currencySymbol: '$',
8
+ quote: 'USD',
9
+ quoteName: 'US Dollar'
10
+ },
11
+ GBP: {
12
+ currencySymbol: '£',
13
+ quote: 'GBP',
14
+ quoteName: 'Great British Pound'
15
+ },
16
+ CAD: {
17
+ currencySymbol: '$',
18
+ quote: 'CAD',
19
+ quoteName: 'Canadian Dollar'
20
+ },
21
+ CNY: {
22
+ currencySymbol: '¥',
23
+ quote: 'CNY',
24
+ quoteName: 'Chinese Yuan Renminbi'
25
+ },
26
+ EUR: { currencySymbol: '€', quote: 'EUR', quoteName: 'Euro' }
27
+ };
28
+
29
+ type TTicker = {
30
+ symbol: string;
31
+ lastPrice: string;
32
+ base: string;
33
+ baseName: string;
34
+ quote: string;
35
+ quoteName: string;
36
+ currencySymbol: string;
37
+ currencyFlag: string;
38
+ lastUpdatedAt: number;
39
+ };
40
+
41
+ /**
42
+ * Returns the exchange rate for the given currency
43
+ * @returns {Promise<Result<IExchangeRates>>}
44
+ */
45
+ export const getExchangeRates = async (): Promise<Result<IExchangeRates>> => {
46
+ try {
47
+ const response = await fetch(`${BLOCKTANK_HOST}/fx/rates/btc`);
48
+ const { tickers } = await response.json();
49
+
50
+ const rates: IExchangeRates = tickers.reduce(
51
+ (acc: IExchangeRates, ticker: TTicker) => {
52
+ return {
53
+ ...acc,
54
+ [ticker.quote]: {
55
+ currencySymbol: ticker.currencySymbol,
56
+ quote: ticker.quote,
57
+ quoteName: ticker.quoteName,
58
+ rate: Math.round(Number(ticker.lastPrice) * 100) / 100,
59
+ lastUpdatedAt: ticker.lastUpdatedAt
60
+ }
61
+ };
62
+ },
63
+ {}
64
+ );
65
+
66
+ return ok(rates);
67
+ } catch (e) {
68
+ return err(e);
69
+ }
70
+ };
@@ -0,0 +1,191 @@
1
+ import { EAddressType, EAvailableNetworks, IKeyDerivationPath } from '../types';
2
+ import { address as bitcoinJSAddress, Network, networks } from 'bitcoinjs-lib';
3
+ import bip39 = require('bip39');
4
+ import * as bitcoin from 'bitcoinjs-lib';
5
+ import { availableNetworks, isValidBech32mEncodedString } from './wallet';
6
+ import { err, ok, Result } from './result';
7
+ import { addressTypes } from '../shapes';
8
+ import { getKeyDerivationPathObject } from './derivation-path';
9
+
10
+ /**
11
+ * Get address for a given scriptPubKey.
12
+ * @param scriptPubKey
13
+ * @param selectedNetwork
14
+ * @returns {string}
15
+ */
16
+ export const getAddressFromScriptPubKey = (
17
+ scriptPubKey: string,
18
+ selectedNetwork: EAvailableNetworks
19
+ ): string => {
20
+ const network = networks[selectedNetwork];
21
+ return bitcoin.address.fromOutputScript(
22
+ Buffer.from(scriptPubKey, 'hex'),
23
+ network
24
+ );
25
+ };
26
+
27
+ /**
28
+ * Get sha256 hash of a given string.
29
+ * @param {string} str
30
+ * @returns {string}
31
+ */
32
+ export const getSha256 = (str: string): string => {
33
+ const buffer = Buffer.from(str, 'utf8');
34
+ const hash = bitcoin.crypto.sha256(buffer);
35
+ return hash.toString('hex');
36
+ };
37
+
38
+ /**
39
+ * Validate address for a given network.
40
+ * If no address is provided, it will attempt to validate the address for all available networks.
41
+ * @param {string} address
42
+ * @param {EAvailableNetworks} network
43
+ * @returns {{isValid: boolean, network: EAvailableNetworks}}
44
+ */
45
+ export const validateAddress = ({
46
+ address,
47
+ network
48
+ }: {
49
+ address: string;
50
+ network?: EAvailableNetworks;
51
+ }): {
52
+ isValid: boolean;
53
+ network: EAvailableNetworks;
54
+ } => {
55
+ try {
56
+ //Validate address for all available networks
57
+ let isValid = false;
58
+ const availableNetworksList = availableNetworks();
59
+
60
+ //Validate address for a specific network
61
+ if (network !== undefined) {
62
+ try {
63
+ bitcoinJSAddress.toOutputScript(address, networks[network]);
64
+ return { isValid: true, network };
65
+ } catch {
66
+ // In the event the normal check fails, determine if this is a taproot address.
67
+ const taprootRes = isValidBech32mEncodedString(address);
68
+ if (taprootRes.isValid && taprootRes.network === network) {
69
+ return { isValid: taprootRes.isValid, network: taprootRes.network };
70
+ }
71
+ }
72
+ return { isValid: false, network };
73
+ }
74
+
75
+ for (let i = 0; i < availableNetworksList.length; i++) {
76
+ const validateRes = validateAddress({
77
+ address,
78
+ network: availableNetworksList[i]
79
+ });
80
+ if (validateRes.isValid) {
81
+ isValid = validateRes.isValid;
82
+ network = validateRes.network;
83
+ break;
84
+ }
85
+ }
86
+ return { isValid, network: network ?? EAvailableNetworks.bitcoin };
87
+ } catch {
88
+ return { isValid: false, network: EAvailableNetworks.bitcoin };
89
+ }
90
+ };
91
+
92
+ /**
93
+ * Returns the derivation path object for the specified addressType and network.
94
+ * @param {EAddressType} addressType
95
+ * @param {EAvailableNetworks} [selectedNetwork]
96
+ * @returns Result<IKeyDerivationPath>
97
+ */
98
+ export const getKeyDerivationPath = ({
99
+ addressType,
100
+ network
101
+ }: {
102
+ addressType: EAddressType;
103
+ network: EAvailableNetworks;
104
+ }): Result<IKeyDerivationPath> => {
105
+ try {
106
+ const keyDerivationPathResponse = getKeyDerivationPathObject({
107
+ network,
108
+ path: addressTypes[addressType].path
109
+ });
110
+ if (keyDerivationPathResponse.isErr()) {
111
+ return err(keyDerivationPathResponse.error.message);
112
+ }
113
+ return ok(keyDerivationPathResponse.value);
114
+ } catch (e) {
115
+ return err(e);
116
+ }
117
+ };
118
+
119
+ /**
120
+ * Get scriptHash for a given address
121
+ * @param {string} address
122
+ * @param {EAvailableNetworks} network
123
+ * @returns {string}
124
+ */
125
+ export const getScriptHash = ({
126
+ address,
127
+ network
128
+ }: {
129
+ address: string;
130
+ network: EAvailableNetworks;
131
+ }): string => {
132
+ try {
133
+ const _network: Network = bitcoin.networks[network];
134
+ const script = bitcoin.address.toOutputScript(address, _network);
135
+ const hash = bitcoin.crypto.sha256(script);
136
+ const reversedHash = Buffer.from(hash.reverse());
137
+ return reversedHash.toString('hex');
138
+ } catch {
139
+ return '';
140
+ }
141
+ };
142
+
143
+ /**
144
+ * Extends bip39's generateMnemonic function.
145
+ * @param {number} [strength]
146
+ * @param {(size: number) => Buffer} [rng]
147
+ * @param {string[]} [wordlist]
148
+ * @returns {string}
149
+ */
150
+ export const generateMnemonic = (
151
+ strength?: number,
152
+ rng?: (size: number) => Buffer,
153
+ wordlist?: string[]
154
+ ): string => {
155
+ return bip39.generateMnemonic(strength, rng, wordlist);
156
+ };
157
+
158
+ /**
159
+ * Attempts to validate the provided mnemonic.
160
+ * @param {string} mnemonic
161
+ * @returns {boolean}
162
+ */
163
+ export const validateMnemonic = (mnemonic = ''): boolean => {
164
+ try {
165
+ return bip39.validateMnemonic(mnemonic);
166
+ } catch {
167
+ return false;
168
+ }
169
+ };
170
+
171
+ /**
172
+ * Determines if the two objects passed as params match.
173
+ * @param obj1
174
+ * @param obj2
175
+ * @returns boolean
176
+ */
177
+ export const objectsMatch = (obj1, obj2): boolean => {
178
+ if (!obj1 || !obj2) {
179
+ return false;
180
+ }
181
+ const obj1Length = Object.keys(obj1).length;
182
+ const obj2Length = Object.keys(obj2).length;
183
+
184
+ if (obj1Length === obj2Length) {
185
+ return Object.keys(obj1).every(
186
+ (key) => key in obj2 && obj2[key] === obj1[key]
187
+ );
188
+ } else {
189
+ return false;
190
+ }
191
+ };
@@ -0,0 +1,7 @@
1
+ export * from './wallet';
2
+ export * from './helpers';
3
+ export * from './exchange-rate';
4
+ export * from './electrum';
5
+ export * from './derivation-path';
6
+ export * from './transaction';
7
+ export * from './result';