mainnet-js 3.1.7 → 4.0.0-next.10

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 (267) hide show
  1. package/dist/module/cache/IndexedDbCache.d.ts +1 -1
  2. package/dist/module/cache/IndexedDbCache.d.ts.map +1 -1
  3. package/dist/module/cache/MemoryCache.d.ts +1 -1
  4. package/dist/module/cache/MemoryCache.d.ts.map +1 -1
  5. package/dist/module/cache/WebStorageCache.d.ts +1 -1
  6. package/dist/module/cache/WebStorageCache.d.ts.map +1 -1
  7. package/dist/module/cache/walletCache.d.ts +16 -6
  8. package/dist/module/cache/walletCache.d.ts.map +1 -1
  9. package/dist/module/cache/walletCache.js +92 -34
  10. package/dist/module/cache/walletCache.js.map +1 -1
  11. package/dist/module/cli.js +1 -2
  12. package/dist/module/cli.js.map +1 -1
  13. package/dist/module/db/index.d.ts +1 -1
  14. package/dist/module/db/index.d.ts.map +1 -1
  15. package/dist/module/db/index.js +1 -1
  16. package/dist/module/db/index.js.map +1 -1
  17. package/dist/module/enum.d.ts +1 -1
  18. package/dist/module/enum.d.ts.map +1 -1
  19. package/dist/module/history/getHistory.d.ts +1 -1
  20. package/dist/module/history/getHistory.d.ts.map +1 -1
  21. package/dist/module/history/getHistory.js +3 -3
  22. package/dist/module/history/getHistory.js.map +1 -1
  23. package/dist/module/index.d.ts +25 -22
  24. package/dist/module/index.d.ts.map +1 -1
  25. package/dist/module/index.js +33 -26
  26. package/dist/module/index.js.map +1 -1
  27. package/dist/module/interface.d.ts +12 -2
  28. package/dist/module/interface.d.ts.map +1 -1
  29. package/dist/module/interface.js.map +1 -1
  30. package/dist/module/libauth.d.ts +1 -1
  31. package/dist/module/libauth.d.ts.map +1 -1
  32. package/dist/module/libauth.js +1 -1
  33. package/dist/module/libauth.js.map +1 -1
  34. package/dist/module/mine/mine.d.ts +2 -7
  35. package/dist/module/mine/mine.d.ts.map +1 -1
  36. package/dist/module/mine/mine.js +6 -27
  37. package/dist/module/mine/mine.js.map +1 -1
  38. package/dist/module/network/Connection.d.ts +1 -12
  39. package/dist/module/network/Connection.d.ts.map +1 -1
  40. package/dist/module/network/Connection.js +24 -33
  41. package/dist/module/network/Connection.js.map +1 -1
  42. package/dist/module/network/ElectrumNetworkProvider.d.ts +16 -17
  43. package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
  44. package/dist/module/network/ElectrumNetworkProvider.js +91 -93
  45. package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
  46. package/dist/module/network/MockNetworkProvider.d.ts +28 -0
  47. package/dist/module/network/MockNetworkProvider.d.ts.map +1 -0
  48. package/dist/module/network/MockNetworkProvider.js +74 -0
  49. package/dist/module/network/MockNetworkProvider.js.map +1 -0
  50. package/dist/module/network/NetworkProvider.d.ts +9 -2
  51. package/dist/module/network/NetworkProvider.d.ts.map +1 -1
  52. package/dist/module/network/configuration.d.ts +2 -4
  53. package/dist/module/network/configuration.d.ts.map +1 -1
  54. package/dist/module/network/configuration.js +25 -50
  55. package/dist/module/network/configuration.js.map +1 -1
  56. package/dist/module/network/constant.d.ts +7 -7
  57. package/dist/module/network/constant.d.ts.map +1 -1
  58. package/dist/module/network/constant.js +21 -24
  59. package/dist/module/network/constant.js.map +1 -1
  60. package/dist/module/network/default.d.ts +5 -3
  61. package/dist/module/network/default.d.ts.map +1 -1
  62. package/dist/module/network/default.js +29 -51
  63. package/dist/module/network/default.js.map +1 -1
  64. package/dist/module/network/index.d.ts +4 -4
  65. package/dist/module/network/index.d.ts.map +1 -1
  66. package/dist/module/network/index.js +2 -2
  67. package/dist/module/network/index.js.map +1 -1
  68. package/dist/module/network/interface.d.ts +0 -6
  69. package/dist/module/network/interface.d.ts.map +1 -1
  70. package/dist/module/rate/ExchangeRate.d.ts +1 -1
  71. package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
  72. package/dist/module/rate/ExchangeRate.js +13 -7
  73. package/dist/module/rate/ExchangeRate.js.map +1 -1
  74. package/dist/module/transaction/Wif.d.ts +3 -3
  75. package/dist/module/transaction/Wif.d.ts.map +1 -1
  76. package/dist/module/transaction/Wif.js +4 -4
  77. package/dist/module/transaction/Wif.js.map +1 -1
  78. package/dist/module/transaction/allocateFee.d.ts +1 -1
  79. package/dist/module/transaction/allocateFee.d.ts.map +1 -1
  80. package/dist/module/transaction/allocateFee.js +2 -2
  81. package/dist/module/transaction/allocateFee.js.map +1 -1
  82. package/dist/module/util/deriveCashaddr.js.map +1 -1
  83. package/dist/module/util/deriveNetwork.js +1 -1
  84. package/dist/module/util/deriveNetwork.js.map +1 -1
  85. package/dist/module/util/getAddrsByXpubKey.js +1 -1
  86. package/dist/module/util/getAddrsByXpubKey.js.map +1 -1
  87. package/dist/module/util/getXPubKey.js +1 -1
  88. package/dist/module/util/getXPubKey.js.map +1 -1
  89. package/dist/module/util/hd.d.ts +2 -0
  90. package/dist/module/util/hd.d.ts.map +1 -1
  91. package/dist/module/util/hd.js +41 -0
  92. package/dist/module/util/hd.js.map +1 -1
  93. package/dist/module/util/index.d.ts +7 -9
  94. package/dist/module/util/index.d.ts.map +1 -1
  95. package/dist/module/util/index.js +7 -9
  96. package/dist/module/util/index.js.map +1 -1
  97. package/dist/module/util/transaction.js +1 -1
  98. package/dist/module/util/transaction.js.map +1 -1
  99. package/dist/module/wallet/Base.d.ts +13 -9
  100. package/dist/module/wallet/Base.d.ts.map +1 -1
  101. package/dist/module/wallet/Base.js +54 -58
  102. package/dist/module/wallet/Base.js.map +1 -1
  103. package/dist/module/wallet/HDWallet.d.ts.map +1 -1
  104. package/dist/module/wallet/HDWallet.js +19 -38
  105. package/dist/module/wallet/HDWallet.js.map +1 -1
  106. package/dist/module/wallet/Util.d.ts +4 -22
  107. package/dist/module/wallet/Util.d.ts.map +1 -1
  108. package/dist/module/wallet/Util.js +75 -102
  109. package/dist/module/wallet/Util.js.map +1 -1
  110. package/dist/module/wallet/Watch.d.ts +24 -5
  111. package/dist/module/wallet/Watch.d.ts.map +1 -1
  112. package/dist/module/wallet/Watch.js +141 -17
  113. package/dist/module/wallet/Watch.js.map +1 -1
  114. package/dist/module/wallet/Wif.d.ts +2 -6
  115. package/dist/module/wallet/Wif.d.ts.map +1 -1
  116. package/dist/module/wallet/Wif.js +3 -69
  117. package/dist/module/wallet/Wif.js.map +1 -1
  118. package/dist/module/wallet/createWallet.d.ts +1 -1
  119. package/dist/module/wallet/createWallet.d.ts.map +1 -1
  120. package/dist/module/wallet/createWallet.js +2 -1
  121. package/dist/module/wallet/createWallet.js.map +1 -1
  122. package/dist/module/wallet/interface.d.ts +3 -2
  123. package/dist/module/wallet/interface.d.ts.map +1 -1
  124. package/dist/module/wallet/model.d.ts +2 -1
  125. package/dist/module/wallet/model.d.ts.map +1 -1
  126. package/dist/module/wallet/model.js +1 -1
  127. package/dist/module/wallet/model.js.map +1 -1
  128. package/package.json +17 -29
  129. package/dist/index.html +0 -9
  130. package/dist/mainnet-3.1.7.js +0 -2066
  131. package/dist/module/network/util.d.ts +0 -3
  132. package/dist/module/network/util.d.ts.map +0 -1
  133. package/dist/module/network/util.js +0 -27
  134. package/dist/module/network/util.js.map +0 -1
  135. package/dist/module/test/expect.d.ts +0 -12
  136. package/dist/module/test/expect.d.ts.map +0 -1
  137. package/dist/module/test/expect.js +0 -47
  138. package/dist/module/test/expect.js.map +0 -1
  139. package/dist/module/test/fetch.d.ts +0 -3
  140. package/dist/module/test/fetch.d.ts.map +0 -1
  141. package/dist/module/test/fetch.js +0 -32
  142. package/dist/module/test/fetch.js.map +0 -1
  143. package/dist/module/util/randomBytes.d.ts +0 -2
  144. package/dist/module/util/randomBytes.d.ts.map +0 -1
  145. package/dist/module/util/randomBytes.js +0 -13
  146. package/dist/module/util/randomBytes.js.map +0 -1
  147. package/dist/tsconfig.tsbuildinfo +0 -1
  148. package/src/cache/IndexedDbCache.test.ts +0 -15
  149. package/src/cache/IndexedDbCache.ts +0 -172
  150. package/src/cache/MemoryCache.test.ts +0 -15
  151. package/src/cache/MemoryCache.ts +0 -32
  152. package/src/cache/WebStorageCache.test.ts +0 -15
  153. package/src/cache/WebStorageCache.ts +0 -38
  154. package/src/cache/index.ts +0 -2
  155. package/src/cache/interface.ts +0 -9
  156. package/src/cache/walletCache.ts +0 -254
  157. package/src/chain.ts +0 -3
  158. package/src/cli.ts +0 -32
  159. package/src/config.ts +0 -23
  160. package/src/constant.ts +0 -27
  161. package/src/db/ExchangeRateProvider.ts +0 -28
  162. package/src/db/StorageProvider.ts +0 -64
  163. package/src/db/index.ts +0 -2
  164. package/src/db/interface.ts +0 -11
  165. package/src/enum.ts +0 -34
  166. package/src/history/getHistory.test.ts +0 -290
  167. package/src/history/getHistory.ts +0 -411
  168. package/src/history/interface.ts +0 -24
  169. package/src/index.ts +0 -48
  170. package/src/interface.ts +0 -72
  171. package/src/libauth.ts +0 -11
  172. package/src/message/index.ts +0 -2
  173. package/src/message/interface.ts +0 -40
  174. package/src/message/signed.test.ts +0 -309
  175. package/src/message/signed.ts +0 -201
  176. package/src/mine/index.ts +0 -1
  177. package/src/mine/mine.test.ts +0 -10
  178. package/src/mine/mine.ts +0 -42
  179. package/src/network/Connection.test.ts +0 -51
  180. package/src/network/Connection.ts +0 -73
  181. package/src/network/ElectrumNetworkProvider.ts +0 -657
  182. package/src/network/NetworkProvider.ts +0 -180
  183. package/src/network/Rpc.test.ts +0 -130
  184. package/src/network/configuration.test.ts +0 -59
  185. package/src/network/configuration.ts +0 -72
  186. package/src/network/constant.ts +0 -43
  187. package/src/network/default.ts +0 -120
  188. package/src/network/electrum.test.ts +0 -28
  189. package/src/network/getRelayFeeCache.test.ts +0 -15
  190. package/src/network/getRelayFeeCache.ts +0 -23
  191. package/src/network/index.ts +0 -14
  192. package/src/network/interface.ts +0 -80
  193. package/src/network/util.test.ts +0 -24
  194. package/src/network/util.ts +0 -30
  195. package/src/rate/ExchangeRate.test.headless.js +0 -35
  196. package/src/rate/ExchangeRate.test.ts +0 -51
  197. package/src/rate/ExchangeRate.ts +0 -142
  198. package/src/test/expect.ts +0 -59
  199. package/src/test/fetch.ts +0 -39
  200. package/src/test/json.test.ts +0 -13
  201. package/src/transaction/Wif.ts +0 -680
  202. package/src/transaction/allocateFee.test.ts +0 -298
  203. package/src/transaction/allocateFee.ts +0 -149
  204. package/src/util/amountInSatoshi.test.ts +0 -27
  205. package/src/util/amountInSatoshi.ts +0 -33
  206. package/src/util/asSendRequestObject.ts +0 -81
  207. package/src/util/base64.test.ts +0 -39
  208. package/src/util/base64.ts +0 -12
  209. package/src/util/browserNotSupported.ts +0 -7
  210. package/src/util/checkForEmptySeed.ts +0 -9
  211. package/src/util/checkUtxos.ts +0 -29
  212. package/src/util/checkWifNetwork.ts +0 -24
  213. package/src/util/convert.test.ts +0 -46
  214. package/src/util/convert.ts +0 -50
  215. package/src/util/delay.ts +0 -3
  216. package/src/util/deriveCashaddr.test.ts +0 -164
  217. package/src/util/deriveCashaddr.ts +0 -143
  218. package/src/util/deriveLockscript.ts +0 -16
  219. package/src/util/deriveNetwork.ts +0 -19
  220. package/src/util/derivePublicKeyHash.test.ts +0 -55
  221. package/src/util/derivePublicKeyHash.ts +0 -64
  222. package/src/util/floor.test.ts +0 -21
  223. package/src/util/floor.ts +0 -4
  224. package/src/util/getAddrsByXpubKey.test.ts +0 -115
  225. package/src/util/getAddrsByXpubKey.ts +0 -86
  226. package/src/util/getRuntimePlatform.test.headless.js +0 -40
  227. package/src/util/getRuntimePlatform.test.ts +0 -5
  228. package/src/util/getRuntimePlatform.ts +0 -31
  229. package/src/util/getUsdRate.ts +0 -5
  230. package/src/util/getXPubKey.ts +0 -39
  231. package/src/util/hash160.test.ts +0 -18
  232. package/src/util/hash160.ts +0 -12
  233. package/src/util/hd.ts +0 -16
  234. package/src/util/header.test.ts +0 -34
  235. package/src/util/header.ts +0 -26
  236. package/src/util/index.ts +0 -33
  237. package/src/util/randomBytes.ts +0 -13
  238. package/src/util/randomInt.test.ts +0 -15
  239. package/src/util/randomInt.ts +0 -4
  240. package/src/util/sanitizeAddress.ts +0 -10
  241. package/src/util/sanitizeUnit.ts +0 -11
  242. package/src/util/satoshiToAmount.test.ts +0 -6
  243. package/src/util/satoshiToAmount.ts +0 -33
  244. package/src/util/sumSendRequestAmounts.ts +0 -34
  245. package/src/util/sumUtxoValue.ts +0 -27
  246. package/src/util/transaction.ts +0 -10
  247. package/src/wallet/Base.ts +0 -1563
  248. package/src/wallet/Cashtokens.test.headless.js +0 -730
  249. package/src/wallet/Cashtokens.test.ts +0 -1411
  250. package/src/wallet/HDWallet.test.ts +0 -1086
  251. package/src/wallet/HDWallet.ts +0 -992
  252. package/src/wallet/Util.test.ts +0 -134
  253. package/src/wallet/Util.ts +0 -191
  254. package/src/wallet/WalletCache.test.ts +0 -45
  255. package/src/wallet/Watch.ts +0 -441
  256. package/src/wallet/Wif.bip39.test.ts +0 -48
  257. package/src/wallet/Wif.test.ts +0 -1189
  258. package/src/wallet/Wif.ts +0 -687
  259. package/src/wallet/Wif.watchOnly.test.ts +0 -58
  260. package/src/wallet/createWallet.ts +0 -238
  261. package/src/wallet/enum.ts +0 -18
  262. package/src/wallet/interface.ts +0 -102
  263. package/src/wallet/model.test.ts +0 -24
  264. package/src/wallet/model.ts +0 -352
  265. package/tsconfig.browser.json +0 -11
  266. package/tsconfig.json +0 -33
  267. package/webpack.config.cjs +0 -132
@@ -1,290 +0,0 @@
1
- import { RegTestWallet, Wallet } from "../wallet/Wif";
2
- import { WalletTypeEnum } from "../wallet/enum";
3
- import { createWallet } from "../wallet/createWallet";
4
- import { mine } from "../mine";
5
- import { encodeCashAddress } from "@bitauth/libauth";
6
- import { toBch } from "../util";
7
-
8
- test("Should get miner history", async () => {
9
- const alice = await RegTestWallet.fromWIF(process.env.PRIVATE_WIF!);
10
- const history = await alice.getHistory();
11
- expect(history.length).toBeGreaterThan(0);
12
- });
13
-
14
- // // This class transforms outputs from electrum to a standard array of history.
15
- test("Should get an address history", async () => {
16
- // Build Alice's wallet from Wallet Import Format string
17
- if (!process.env.PRIVATE_WIF) {
18
- throw Error("Attempted to pass an empty WIF");
19
- } else {
20
- let alice = await RegTestWallet.fromWIF(process.env.PRIVATE_WIF); // insert WIF from #1
21
- const bob = await createWallet({
22
- type: WalletTypeEnum.Wif,
23
- network: "regtest",
24
- });
25
- const charlie = await createWallet({
26
- type: WalletTypeEnum.Wif,
27
- network: "regtest",
28
- });
29
- let sendResponse = await alice.send([
30
- {
31
- cashaddr: bob.cashaddr!,
32
- value: 31000n,
33
- },
34
- {
35
- cashaddr: charlie.cashaddr!,
36
- value: 41000n,
37
- },
38
- ]);
39
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
40
- await bob.send([
41
- {
42
- cashaddr: charlie.cashaddr!,
43
- value: 2100n,
44
- },
45
- ]);
46
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 1 });
47
- await bob.send([
48
- {
49
- cashaddr: alice.cashaddr!,
50
- value: 2100n,
51
- },
52
- ]);
53
- expect(sendResponse!.txId!.length).toBe(64);
54
- expect(toBch(sendResponse.balance!)).toBeGreaterThan(0.01);
55
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
56
-
57
- // Build Bob's wallet from a public address, check his balance.
58
- const bobHistory = await bob.getHistory();
59
- expect(bobHistory[0].valueChange).toBe(-2320);
60
- expect(
61
- bobHistory[0].outputs.some(
62
- (output) => output.address === alice.getDepositAddress()
63
- )
64
- ).toBe(true);
65
- expect(
66
- bobHistory[0].inputs.some(
67
- (input) => input.address === bob.getDepositAddress()
68
- )
69
- ).toBe(true);
70
- expect(bobHistory[1].valueChange).toBe(-2320);
71
- expect(
72
- bobHistory[1].inputs.some(
73
- (input) => input.address === bob.getDepositAddress()
74
- )
75
- ).toBe(true);
76
- expect(
77
- bobHistory[1].outputs.some(
78
- (output) => output.address === charlie.getDepositAddress()
79
- )
80
- ).toBe(true);
81
- expect(bobHistory[2].valueChange).toBe(31000);
82
- expect(bobHistory[2].balance).toBe(31000);
83
- expect(bobHistory[2].fee).not.toBe(0);
84
- expect(
85
- bobHistory[2].inputs.some(
86
- (input) => input.address === alice.getDepositAddress()
87
- )
88
- ).toBe(true);
89
- }
90
- });
91
-
92
- // This class transforms outputs from electrum to a standard array of history.
93
- test("Should get a history with multi-party sends", async () => {
94
- // Build Alice's wallet from Wallet Import Format string
95
- if (!process.env.PRIVATE_WIF) {
96
- throw Error("Attempted to pass an empty WIF");
97
- } else {
98
- let alice = await RegTestWallet.fromWIF(process.env.PRIVATE_WIF); // insert WIF from #1
99
- const bob = await createWallet({
100
- type: WalletTypeEnum.Wif,
101
- network: "regtest",
102
- });
103
- const charlie = await createWallet({
104
- type: WalletTypeEnum.Wif,
105
- network: "regtest",
106
- });
107
- let sendResponse = await alice.send([
108
- {
109
- cashaddr: bob.cashaddr!,
110
- value: 31000n,
111
- },
112
- ]);
113
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
114
- await bob.send([
115
- {
116
- cashaddr: charlie.cashaddr!,
117
- value: 2100n,
118
- },
119
- ]);
120
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 1 });
121
- await bob.send([
122
- {
123
- cashaddr: alice.cashaddr!,
124
- value: 2100n,
125
- },
126
- ]);
127
- expect(sendResponse!.txId!.length).toBe(64);
128
- expect(toBch(sendResponse.balance!)).toBeGreaterThan(0.01);
129
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 1 });
130
-
131
- // Build Bob's wallet from a public address, check his balance.
132
- const bobHistory = await bob.getHistory();
133
-
134
- expect(bobHistory[1].fee).toBeGreaterThan(120);
135
- expect(bobHistory[1].fee).toBe(220);
136
- expect(bobHistory[0].valueChange).toBe(-2320);
137
- expect(
138
- bobHistory[0].outputs.some(
139
- (output) => output.address === alice.getDepositAddress()
140
- )
141
- ).toBe(true);
142
- expect(
143
- bobHistory[0].inputs.some(
144
- (input) => input.address === bob.getDepositAddress()
145
- )
146
- ).toBe(true);
147
- expect(bobHistory[1].valueChange).toBe(-2320);
148
- expect(
149
- bobHistory[1].outputs.some(
150
- (output) => output.address === charlie.getDepositAddress()
151
- )
152
- ).toBe(true);
153
- expect(
154
- bobHistory[1].inputs.some(
155
- (input) => input.address === bob.getDepositAddress()
156
- )
157
- ).toBe(true);
158
-
159
- expect(bobHistory[2].valueChange).toBe(31000);
160
- expect(bobHistory[2].fee).not.toBe(0);
161
- expect(
162
- bobHistory[2].inputs.some(
163
- (input) => input.address === alice.getDepositAddress()
164
- )
165
- ).toBe(true);
166
- }
167
- });
168
-
169
- // This class transforms outputs from electrum to a standard array of history.
170
- test("Should cut results with a longer history to given count", async () => {
171
- // Build Alice's wallet from Wallet Import Format string
172
- if (!process.env.PRIVATE_WIF) {
173
- throw Error("Attempted to pass an empty WIF");
174
- } else {
175
- let alice = await RegTestWallet.fromWIF(process.env.PRIVATE_WIF); // insert WIF from #1
176
- const bob = await createWallet({
177
- type: WalletTypeEnum.Wif,
178
- network: "regtest",
179
- });
180
- const charlie = await createWallet({
181
- type: WalletTypeEnum.Wif,
182
- network: "regtest",
183
- });
184
- let sendResponse = await alice.send([
185
- {
186
- cashaddr: bob.cashaddr!,
187
- value: 31000n,
188
- },
189
- ]);
190
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
191
- await bob.send([
192
- {
193
- cashaddr: charlie.cashaddr!,
194
- value: 2100n,
195
- },
196
- {
197
- cashaddr: alice.cashaddr!,
198
- value: 2100n,
199
- },
200
- {
201
- cashaddr: alice.cashaddr!,
202
- value: 2100n,
203
- },
204
- ]);
205
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 1 });
206
- expect(sendResponse!.txId!.length).toBe(64);
207
- expect(toBch(sendResponse.balance!)).toBeGreaterThan(0.01);
208
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
209
-
210
- // Build Bob's wallet from a public address, check his balance.
211
- const bobHistory = await bob.getHistory({
212
- unit: "sat",
213
- start: 0,
214
- count: 2,
215
- });
216
- expect(bobHistory.length).toBe(2);
217
-
218
- expect(bobHistory[0].valueChange).toBe(-6588);
219
- expect(
220
- bobHistory[0].outputs.some(
221
- (output) => output.address === alice.getDepositAddress()
222
- )
223
- ).toBe(true);
224
- expect(bobHistory[1].valueChange).toBe(31000);
225
- expect(
226
- bobHistory[1].outputs.some(
227
- (output) => output.address === alice.getDepositAddress()
228
- )
229
- ).toBe(true);
230
- }
231
- });
232
-
233
- // This class transforms outputs from electrum to a standard array of history.
234
- test("Should handle input and fee from many utxos", async () => {
235
- // Build Alice's wallet from Wallet Import Format string
236
- if (!process.env.PRIVATE_WIF) {
237
- throw Error("Attempted to pass an empty WIF");
238
- } else {
239
- let alice = await RegTestWallet.fromWIF(process.env.PRIVATE_WIF); // insert WIF from #1
240
- const bob = await createWallet({
241
- type: WalletTypeEnum.Wif,
242
- network: "regtest",
243
- });
244
- const charlie = await createWallet({
245
- type: WalletTypeEnum.Wif,
246
- network: "regtest",
247
- });
248
- let sendResponse = await alice.send([
249
- {
250
- cashaddr: bob.cashaddr!,
251
- value: 600n,
252
- },
253
- {
254
- cashaddr: bob.cashaddr!,
255
- value: 600n,
256
- },
257
- {
258
- cashaddr: bob.cashaddr!,
259
- value: 600n,
260
- },
261
- {
262
- cashaddr: bob.cashaddr!,
263
- value: 600n,
264
- },
265
- ]);
266
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
267
- await bob.sendMax(charlie.cashaddr!);
268
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 1 });
269
- expect(sendResponse!.txId!.length).toBe(64);
270
- expect(toBch(sendResponse.balance!)).toBeGreaterThan(0.01);
271
- await mine({ cashaddr: alice.getDepositAddress(), blocks: 10 });
272
-
273
- // Build Bob's wallet from a public address, check his balance.
274
- const bobHistory = await bob.getHistory({
275
- unit: "sat",
276
- });
277
-
278
- expect(bobHistory[0].valueChange).toBeLessThan(-1700);
279
- expect(
280
- bobHistory[0].outputs.some(
281
- (output) => output.address === charlie.getDepositAddress()
282
- )
283
- ).toBe(true);
284
- expect(
285
- bobHistory[1].inputs.some(
286
- (input) => input.address === alice.getDepositAddress()
287
- )
288
- ).toBe(true);
289
- }
290
- });
@@ -1,411 +0,0 @@
1
- import {
2
- binToHex,
3
- decodeTransaction,
4
- hexToBin,
5
- lockingBytecodeToCashAddress,
6
- CashAddressNetworkPrefix,
7
- decodeCashAddress,
8
- TransactionCommon,
9
- assertSuccess,
10
- Opcodes,
11
- } from "@bitauth/libauth";
12
- import { UnitEnum } from "../enum.js";
13
- import NetworkProvider from "../network/NetworkProvider.js";
14
- import { TxI } from "../interface.js";
15
- import { TransactionHistoryItem, InOutput } from "./interface.js";
16
- import { ExchangeRate } from "../rate/ExchangeRate.js";
17
- import { sanitizeUnit } from "../util/sanitizeUnit.js";
18
- import { bchParam } from "../chain.js";
19
-
20
- type Transaction = TransactionCommon & {
21
- size: number;
22
- blockHeight: number;
23
- timestamp?: number;
24
- hash: string;
25
- };
26
-
27
- export const getHistory = async ({
28
- addresses,
29
- provider,
30
- unit = "sat",
31
- fromHeight = 0,
32
- toHeight = -1,
33
- start = 0,
34
- count = -1,
35
- rawHistory,
36
- }: {
37
- addresses: string[];
38
- provider: NetworkProvider;
39
- unit?: UnitEnum;
40
- fromHeight?: number;
41
- toHeight?: number;
42
- start?: number;
43
- count?: number;
44
- rawHistory?: TxI[];
45
- }): Promise<TransactionHistoryItem[]> => {
46
- if (!addresses.length) {
47
- return [];
48
- }
49
-
50
- if (count === -1) {
51
- count = 1e10;
52
- }
53
-
54
- let history: TxI[];
55
- if (rawHistory) {
56
- history = rawHistory.slice(start, start + count);
57
- } else {
58
- const allHistory = (
59
- await Promise.all(
60
- addresses.map(async (address) =>
61
- provider.getHistory(address, fromHeight, toHeight)
62
- )
63
- )
64
- ).flat();
65
-
66
- // Dedup using Set instead of O(N²) findIndex
67
- const seen = new Set<string>();
68
- const deduped: TxI[] = [];
69
- for (const item of allHistory) {
70
- if (!seen.has(item.tx_hash)) {
71
- seen.add(item.tx_hash);
72
- deduped.push(item);
73
- }
74
- }
75
-
76
- history = deduped
77
- .sort((a, b) =>
78
- a.height <= 0 || b.height <= 0
79
- ? a.height - b.height
80
- : b.height - a.height
81
- )
82
- .slice(start, start + count);
83
- }
84
-
85
- // Collect unique heights for header fetch
86
- const uniqueHeightsSet = new Set<number>();
87
- for (const tx of history) {
88
- if (tx.height > 0) uniqueHeightsSet.add(tx.height);
89
- }
90
- const uniqueHeights = [...uniqueHeightsSet];
91
-
92
- // Batch fetch headers and history transactions in parallel
93
- const historyHashes = history.map((tx) => tx.tx_hash);
94
- const [headerMap, txHexMap] = await Promise.all([
95
- uniqueHeights.length > 0 ? provider.getHeaders(uniqueHeights) : new Map(),
96
- provider.getRawTransactions(historyHashes),
97
- ] as const);
98
-
99
- const timestampMap: Record<number, number> = {};
100
- for (const [height, header] of headerMap) {
101
- timestampMap[height] = header.timestamp;
102
- }
103
-
104
- // Precompute binToHex for each input's outpoint hash once
105
- const inputOutpointHashes = new WeakMap<Uint8Array, string>();
106
- const getOutpointHash = (bytes: Uint8Array): string => {
107
- let hash = inputOutpointHashes.get(bytes);
108
- if (hash === undefined) {
109
- hash = binToHex(bytes);
110
- inputOutpointHashes.set(bytes, hash);
111
- }
112
- return hash;
113
- };
114
-
115
- const historicTransactions = history.map((tx) => {
116
- const txHex = txHexMap.get(tx.tx_hash)!;
117
- const transactionCommon = decodeTransaction(hexToBin(txHex));
118
- if (typeof transactionCommon === "string") {
119
- throw transactionCommon;
120
- }
121
-
122
- const transaction = transactionCommon as Transaction;
123
- transaction.blockHeight = tx.height;
124
- transaction.timestamp = timestampMap[tx.height];
125
- transaction.hash = tx.tx_hash;
126
- transaction.size = txHex.length / 2;
127
-
128
- return transaction;
129
- });
130
-
131
- // Collect unique prevout hashes using Set, excluding already-fetched txs
132
- const ZERO_HASH =
133
- "0000000000000000000000000000000000000000000000000000000000000000";
134
- const prevoutHashSet = new Set<string>();
135
- for (const tx of historicTransactions) {
136
- for (const input of tx.inputs) {
137
- const hash = getOutpointHash(input.outpointTransactionHash);
138
- if (hash !== ZERO_HASH && !txHexMap.has(hash)) {
139
- prevoutHashSet.add(hash);
140
- }
141
- }
142
- }
143
-
144
- // Batch fetch prevout transactions
145
- const prevoutHashes = [...prevoutHashSet];
146
- const prevoutHexMap = await provider.getRawTransactions(prevoutHashes);
147
-
148
- // Build prevout transaction map (decode all prevout txs)
149
- const prevoutTransactionMap: Record<string, TransactionCommon> = {};
150
- const allPrevoutSources = new Map([...txHexMap, ...prevoutHexMap]);
151
- for (const tx of historicTransactions) {
152
- for (const input of tx.inputs) {
153
- const hash = getOutpointHash(input.outpointTransactionHash);
154
- if (hash === ZERO_HASH || prevoutTransactionMap[hash]) continue;
155
-
156
- const hex = allPrevoutSources.get(hash);
157
- if (!hex) continue;
158
-
159
- const decoded = decodeTransaction(hexToBin(hex));
160
- if (typeof decoded === "string") {
161
- throw decoded;
162
- }
163
- prevoutTransactionMap[hash] = decoded;
164
- }
165
- }
166
-
167
- const decoded = assertSuccess(decodeCashAddress(addresses[0]));
168
- const prefix = decoded.prefix as CashAddressNetworkPrefix;
169
-
170
- const addressCache: Record<any, string> = {};
171
- const addressSet = new Set(addresses);
172
-
173
- // map decoded transaction data to TransactionHistoryItem
174
- const historyItems = historicTransactions.map((tx) => {
175
- const result = {} as TransactionHistoryItem;
176
-
177
- let inputTotalValue = 0n;
178
- let outputTotalValue = 0n;
179
-
180
- const isCoinbase =
181
- tx.inputs.length === 1 &&
182
- tx.inputs[0].outpointTransactionHash.every((b) => b === 0);
183
-
184
- result.inputs = tx.inputs.map((input): InOutput => {
185
- if (isCoinbase) {
186
- const halvings = Math.floor(tx.blockHeight / 210000);
187
- const subsidy = Math.floor(5000000000 / 2 ** halvings);
188
- inputTotalValue += BigInt(subsidy);
189
-
190
- return {
191
- address: "coinbase",
192
- value: subsidy,
193
- };
194
- }
195
-
196
- const prevoutTx =
197
- prevoutTransactionMap[getOutpointHash(input.outpointTransactionHash)];
198
- if (!prevoutTx) {
199
- throw new Error("Could not find prevout transaction");
200
- }
201
-
202
- const prevoutOutput = prevoutTx.outputs[input.outpointIndex];
203
- if (!prevoutOutput) {
204
- throw new Error("Could not find prevout output");
205
- }
206
-
207
- const cached = addressCache[prevoutOutput.lockingBytecode as any];
208
- let address: string;
209
- if (!cached) {
210
- address = assertSuccess(
211
- lockingBytecodeToCashAddress({
212
- bytecode: prevoutOutput.lockingBytecode,
213
- prefix: prefix,
214
- })
215
- ).address;
216
- addressCache[prevoutOutput.lockingBytecode as any] = address;
217
- } else {
218
- address = cached;
219
- }
220
-
221
- inputTotalValue += prevoutOutput.valueSatoshis;
222
-
223
- return {
224
- address: address,
225
- value: Number(prevoutOutput.valueSatoshis),
226
- token: prevoutOutput.token
227
- ? {
228
- category: binToHex(prevoutOutput.token.category),
229
- amount: prevoutOutput.token.amount,
230
- nft: prevoutOutput.token.nft
231
- ? {
232
- capability: prevoutOutput.token.nft.capability,
233
- commitment: binToHex(prevoutOutput.token.nft.commitment),
234
- }
235
- : undefined,
236
- }
237
- : undefined,
238
- };
239
- });
240
-
241
- result.outputs = tx.outputs.map((output): InOutput => {
242
- const cached = addressCache[output.lockingBytecode as any];
243
- let address: string;
244
- if (!cached) {
245
- if (output.lockingBytecode[0] === Opcodes.OP_RETURN) {
246
- address = `OP_RETURN: ${binToHex(output.lockingBytecode)}`;
247
- } else {
248
- address = assertSuccess(
249
- lockingBytecodeToCashAddress({
250
- bytecode: output.lockingBytecode,
251
- prefix: prefix,
252
- })
253
- ).address;
254
- addressCache[output.lockingBytecode as any] = address;
255
- }
256
- } else {
257
- address = cached;
258
- }
259
-
260
- outputTotalValue += output.valueSatoshis;
261
-
262
- return {
263
- address: address,
264
- value: Number(output.valueSatoshis),
265
- token: output.token
266
- ? {
267
- category: binToHex(output.token.category),
268
- amount: output.token.amount,
269
- nft: output.token.nft
270
- ? {
271
- capability: output.token.nft.capability,
272
- commitment: binToHex(output.token.nft.commitment),
273
- }
274
- : undefined,
275
- }
276
- : undefined,
277
- };
278
- });
279
-
280
- result.blockHeight = tx.blockHeight;
281
- result.timestamp = tx.timestamp;
282
- result.hash = tx.hash;
283
- result.size = tx.size;
284
- result.fee = Number(inputTotalValue - outputTotalValue);
285
-
286
- if (isCoinbase && result.fee) {
287
- // will indicate the fees collected by the miner
288
- result.fee = -result.fee;
289
- }
290
-
291
- return result;
292
- });
293
-
294
- // compute value changes using Set for O(1) address lookup
295
- historyItems.forEach((tx) => {
296
- let satoshiBalance = 0;
297
- const ftTokenBalances: Record<string, bigint> = {};
298
- const nftTokenBalances: Record<string, bigint> = {};
299
-
300
- tx.inputs.forEach((input) => {
301
- if (addressSet.has(input.address)) {
302
- satoshiBalance -= input.value;
303
-
304
- if (input.token?.amount) {
305
- ftTokenBalances[input.token.category] =
306
- (ftTokenBalances[input.token.category] || BigInt(0)) -
307
- input.token.amount;
308
- }
309
-
310
- if (input.token?.nft?.capability) {
311
- nftTokenBalances[input.token.category] =
312
- (nftTokenBalances[input.token.category] || BigInt(0)) - 1n;
313
- }
314
- }
315
- });
316
- tx.outputs.forEach((output) => {
317
- if (addressSet.has(output.address)) {
318
- satoshiBalance += Number(output.value);
319
-
320
- if (output.token?.amount) {
321
- ftTokenBalances[output.token.category] =
322
- (ftTokenBalances[output.token.category] || BigInt(0)) +
323
- output.token.amount;
324
- }
325
-
326
- if (output.token?.nft?.capability) {
327
- nftTokenBalances[output.token.category] =
328
- (nftTokenBalances[output.token.category] || BigInt(0)) + 1n;
329
- }
330
- }
331
- });
332
-
333
- tx.valueChange = satoshiBalance;
334
- tx.tokenAmountChanges = Object.entries(ftTokenBalances).map(
335
- ([category, amount]) => ({
336
- category,
337
- amount,
338
- nftAmount: BigInt(0),
339
- })
340
- );
341
-
342
- for (const [category, nftAmount] of Object.entries(nftTokenBalances)) {
343
- const tokenChange = tx.tokenAmountChanges.find(
344
- (tokenChange) => tokenChange.category === category
345
- );
346
- if (tokenChange) {
347
- tokenChange.nftAmount = nftAmount;
348
- } else {
349
- tx.tokenAmountChanges.push({
350
- category: category,
351
- amount: BigInt(0),
352
- nftAmount,
353
- });
354
- }
355
- }
356
- });
357
-
358
- // order transactions in a way such that receives are always ordered before sends, per block
359
- historyItems.sort(
360
- (a, b) =>
361
- (a.blockHeight <= 0 || b.blockHeight <= 0
362
- ? a.blockHeight - b.blockHeight
363
- : b.blockHeight - a.blockHeight) || a.valueChange - b.valueChange
364
- );
365
-
366
- // backfill the balances
367
- let prevBalance = (
368
- await Promise.all(addresses.map((address) => provider.getBalance(address)))
369
- ).reduce((a, b) => Number(a) + Number(b), 0);
370
-
371
- let prevValueChange = 0;
372
- historyItems.forEach((tx) => {
373
- tx.balance = prevBalance - prevValueChange;
374
- prevBalance = tx.balance;
375
- prevValueChange = tx.valueChange;
376
- });
377
-
378
- // convert units if needed — fetch exchange rate once
379
- if (!(unit as string).includes("sat")) {
380
- const sanitizedUnit = sanitizeUnit(unit);
381
- let rate: number = 0;
382
- if (sanitizedUnit !== UnitEnum.BCH && sanitizedUnit !== UnitEnum.SAT) {
383
- rate = await ExchangeRate.get(unit);
384
- }
385
-
386
- const subUnits = Number(bchParam.subUnits);
387
- const convertSatToUnit = (satValue: number): number => {
388
- if (sanitizedUnit === UnitEnum.BCH) {
389
- return satValue / subUnits;
390
- }
391
- // currency conversion matching satoshiToAmount behavior
392
- const currencyValue = Number((satValue * (rate / subUnits)).toFixed(2));
393
- return currencyValue;
394
- };
395
-
396
- for (const tx of historyItems) {
397
- for (const input of tx.inputs) {
398
- input.value = convertSatToUnit(input.value);
399
- }
400
-
401
- for (const output of tx.outputs) {
402
- output.value = convertSatToUnit(output.value);
403
- }
404
-
405
- tx.valueChange = convertSatToUnit(tx.valueChange);
406
- tx.balance = convertSatToUnit(tx.balance);
407
- }
408
- }
409
-
410
- return historyItems;
411
- };