@bsv/wallet-toolbox 1.3.23 → 1.3.25

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 (262) hide show
  1. package/docs/client.md +99 -59
  2. package/docs/storage.md +55 -75
  3. package/docs/wallet.md +99 -59
  4. package/mobile/out/src/Wallet.d.ts +1 -1
  5. package/mobile/out/src/Wallet.d.ts.map +1 -1
  6. package/mobile/out/src/Wallet.js +16 -6
  7. package/mobile/out/src/Wallet.js.map +1 -1
  8. package/mobile/out/src/monitor/Monitor.d.ts.map +1 -1
  9. package/mobile/out/src/monitor/Monitor.js +6 -4
  10. package/mobile/out/src/monitor/Monitor.js.map +1 -1
  11. package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts +1 -1
  12. package/mobile/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
  13. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
  14. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
  15. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
  16. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
  17. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
  18. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
  19. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts +19 -1
  20. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
  21. package/mobile/out/src/services/ServiceCollection.d.ts +38 -0
  22. package/mobile/out/src/services/ServiceCollection.d.ts.map +1 -1
  23. package/mobile/out/src/services/ServiceCollection.js +85 -0
  24. package/mobile/out/src/services/ServiceCollection.js.map +1 -1
  25. package/mobile/out/src/services/Services.d.ts +11 -2
  26. package/mobile/out/src/services/Services.d.ts.map +1 -1
  27. package/mobile/out/src/services/Services.js +159 -68
  28. package/mobile/out/src/services/Services.js.map +1 -1
  29. package/mobile/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -0
  30. package/mobile/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -0
  31. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +1 -1
  32. package/mobile/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
  33. package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts +1 -1
  34. package/mobile/out/src/services/chaintracker/chaintracks/index.d.ts.map +1 -1
  35. package/mobile/out/src/services/chaintracker/chaintracks/index.js +1 -1
  36. package/mobile/out/src/services/chaintracker/chaintracks/index.js.map +1 -1
  37. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
  38. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  39. package/mobile/out/src/services/createDefaultWalletServicesOptions.js +15 -1
  40. package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  41. package/mobile/out/src/services/providers/ARC.d.ts +3 -2
  42. package/mobile/out/src/services/providers/ARC.d.ts.map +1 -1
  43. package/mobile/out/src/services/providers/ARC.js +5 -4
  44. package/mobile/out/src/services/providers/ARC.js.map +1 -1
  45. package/mobile/out/src/signer/methods/internalizeAction.d.ts +2 -2
  46. package/mobile/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
  47. package/mobile/out/src/signer/methods/internalizeAction.js +3 -13
  48. package/mobile/out/src/signer/methods/internalizeAction.js.map +1 -1
  49. package/mobile/out/src/storage/StorageProvider.d.ts +5 -6
  50. package/mobile/out/src/storage/StorageProvider.d.ts.map +1 -1
  51. package/mobile/out/src/storage/StorageProvider.js +75 -101
  52. package/mobile/out/src/storage/StorageProvider.js.map +1 -1
  53. package/mobile/out/src/storage/WalletStorageManager.d.ts +2 -2
  54. package/mobile/out/src/storage/WalletStorageManager.d.ts.map +1 -1
  55. package/mobile/out/src/storage/methods/createAction.d.ts.map +1 -1
  56. package/mobile/out/src/storage/methods/createAction.js +5 -1
  57. package/mobile/out/src/storage/methods/createAction.js.map +1 -1
  58. package/mobile/out/src/storage/methods/generateChange.d.ts +0 -24
  59. package/mobile/out/src/storage/methods/generateChange.d.ts.map +1 -1
  60. package/mobile/out/src/storage/methods/generateChange.js +2 -50
  61. package/mobile/out/src/storage/methods/generateChange.js.map +1 -1
  62. package/mobile/out/src/storage/methods/getBeefForTransaction.js +3 -2
  63. package/mobile/out/src/storage/methods/getBeefForTransaction.js.map +1 -1
  64. package/mobile/out/src/storage/methods/internalizeAction.d.ts +2 -10
  65. package/mobile/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
  66. package/mobile/out/src/storage/methods/internalizeAction.js +17 -1
  67. package/mobile/out/src/storage/methods/internalizeAction.js.map +1 -1
  68. package/mobile/out/src/storage/methods/processAction.d.ts +16 -1
  69. package/mobile/out/src/storage/methods/processAction.d.ts.map +1 -1
  70. package/mobile/out/src/storage/methods/processAction.js +4 -1
  71. package/mobile/out/src/storage/methods/processAction.js.map +1 -1
  72. package/mobile/out/src/storage/methods/utils.d.ts +25 -0
  73. package/mobile/out/src/storage/methods/utils.d.ts.map +1 -0
  74. package/mobile/out/src/storage/methods/utils.js +53 -0
  75. package/mobile/out/src/storage/methods/utils.js.map +1 -0
  76. package/mobile/out/src/storage/remoting/StorageClient.d.ts +2 -2
  77. package/mobile/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
  78. package/mobile/out/src/storage/remoting/StorageClient.js.map +1 -1
  79. package/mobile/out/src/storage/remoting/StorageMobile.d.ts +2 -2
  80. package/mobile/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
  81. package/mobile/out/src/storage/remoting/StorageMobile.js.map +1 -1
  82. package/mobile/out/src/utility/utilityHelpers.d.ts +1 -1
  83. package/mobile/out/src/utility/utilityHelpers.d.ts.map +1 -1
  84. package/mobile/out/src/utility/utilityHelpers.js +3 -3
  85. package/mobile/out/src/utility/utilityHelpers.js.map +1 -1
  86. package/mobile/package-lock.json +7 -6
  87. package/mobile/package.json +2 -2
  88. package/out/src/Wallet.d.ts +1 -1
  89. package/out/src/Wallet.d.ts.map +1 -1
  90. package/out/src/Wallet.js +16 -6
  91. package/out/src/Wallet.js.map +1 -1
  92. package/out/src/monitor/Monitor.d.ts.map +1 -1
  93. package/out/src/monitor/Monitor.js +6 -4
  94. package/out/src/monitor/Monitor.js.map +1 -1
  95. package/out/src/monitor/tasks/TaskNewHeader.d.ts +1 -1
  96. package/out/src/monitor/tasks/TaskNewHeader.d.ts.map +1 -1
  97. package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
  98. package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
  99. package/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
  100. package/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
  101. package/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
  102. package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
  103. package/out/src/sdk/WalletStorage.interfaces.d.ts +19 -1
  104. package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
  105. package/out/src/services/ServiceCollection.d.ts +38 -0
  106. package/out/src/services/ServiceCollection.d.ts.map +1 -1
  107. package/out/src/services/ServiceCollection.js +85 -0
  108. package/out/src/services/ServiceCollection.js.map +1 -1
  109. package/out/src/services/Services.d.ts +11 -2
  110. package/out/src/services/Services.d.ts.map +1 -1
  111. package/out/src/services/Services.js +159 -68
  112. package/out/src/services/Services.js.map +1 -1
  113. package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts +2 -0
  114. package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts.map +1 -0
  115. package/out/src/services/__tests/ArcGorillaPool.man.test.js +93 -0
  116. package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +1 -0
  117. package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.d.ts.map +1 -0
  118. package/out/src/services/chaintracker/chaintracks/Api/BlockHeaderApi.js.map +1 -0
  119. package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts +1 -1
  120. package/out/src/services/chaintracker/chaintracks/ChaintracksServiceClient.d.ts.map +1 -1
  121. package/out/src/services/chaintracker/chaintracks/index.d.ts +1 -1
  122. package/out/src/services/chaintracker/chaintracks/index.d.ts.map +1 -1
  123. package/out/src/services/chaintracker/chaintracks/index.js +1 -1
  124. package/out/src/services/chaintracker/chaintracks/index.js.map +1 -1
  125. package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts +144 -0
  126. package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.d.ts.map +1 -0
  127. package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js +463 -0
  128. package/out/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.js.map +1 -0
  129. package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts +20 -0
  130. package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.d.ts.map +1 -0
  131. package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js +31 -0
  132. package/out/src/services/chaintracker/chaintracks/util/dirtyHashes.js.map +1 -0
  133. package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
  134. package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  135. package/out/src/services/createDefaultWalletServicesOptions.js +15 -1
  136. package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  137. package/out/src/services/providers/ARC.d.ts +3 -2
  138. package/out/src/services/providers/ARC.d.ts.map +1 -1
  139. package/out/src/services/providers/ARC.js +5 -4
  140. package/out/src/services/providers/ARC.js.map +1 -1
  141. package/out/src/signer/methods/internalizeAction.d.ts +2 -2
  142. package/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
  143. package/out/src/signer/methods/internalizeAction.js +3 -13
  144. package/out/src/signer/methods/internalizeAction.js.map +1 -1
  145. package/out/src/storage/StorageKnex.d.ts.map +1 -1
  146. package/out/src/storage/StorageKnex.js +50 -2
  147. package/out/src/storage/StorageKnex.js.map +1 -1
  148. package/out/src/storage/StorageProvider.d.ts +5 -6
  149. package/out/src/storage/StorageProvider.d.ts.map +1 -1
  150. package/out/src/storage/StorageProvider.js +75 -101
  151. package/out/src/storage/StorageProvider.js.map +1 -1
  152. package/out/src/storage/WalletStorageManager.d.ts +2 -2
  153. package/out/src/storage/WalletStorageManager.d.ts.map +1 -1
  154. package/out/src/storage/__test/StorageIdb.test.js +1 -0
  155. package/out/src/storage/__test/StorageIdb.test.js.map +1 -1
  156. package/out/src/storage/__test/adminStats.man.test.js +2 -0
  157. package/out/src/storage/__test/adminStats.man.test.js.map +1 -1
  158. package/out/src/storage/methods/createAction.d.ts.map +1 -1
  159. package/out/src/storage/methods/createAction.js +5 -1
  160. package/out/src/storage/methods/createAction.js.map +1 -1
  161. package/out/src/storage/methods/generateChange.d.ts +0 -24
  162. package/out/src/storage/methods/generateChange.d.ts.map +1 -1
  163. package/out/src/storage/methods/generateChange.js +2 -50
  164. package/out/src/storage/methods/generateChange.js.map +1 -1
  165. package/out/src/storage/methods/getBeefForTransaction.js +3 -2
  166. package/out/src/storage/methods/getBeefForTransaction.js.map +1 -1
  167. package/out/src/storage/methods/internalizeAction.d.ts +2 -10
  168. package/out/src/storage/methods/internalizeAction.d.ts.map +1 -1
  169. package/out/src/storage/methods/internalizeAction.js +17 -1
  170. package/out/src/storage/methods/internalizeAction.js.map +1 -1
  171. package/out/src/storage/methods/processAction.d.ts +16 -1
  172. package/out/src/storage/methods/processAction.d.ts.map +1 -1
  173. package/out/src/storage/methods/processAction.js +4 -1
  174. package/out/src/storage/methods/processAction.js.map +1 -1
  175. package/out/src/storage/methods/utils.Buffer.d.ts +21 -0
  176. package/out/src/storage/methods/utils.Buffer.d.ts.map +1 -0
  177. package/out/src/storage/methods/utils.Buffer.js +37 -0
  178. package/out/src/storage/methods/utils.Buffer.js.map +1 -0
  179. package/out/src/storage/methods/utils.d.ts +25 -0
  180. package/out/src/storage/methods/utils.d.ts.map +1 -0
  181. package/out/src/storage/methods/utils.js +53 -0
  182. package/out/src/storage/methods/utils.js.map +1 -0
  183. package/out/src/storage/remoting/StorageClient.d.ts +2 -2
  184. package/out/src/storage/remoting/StorageClient.d.ts.map +1 -1
  185. package/out/src/storage/remoting/StorageClient.js.map +1 -1
  186. package/out/src/storage/remoting/StorageMobile.d.ts +2 -2
  187. package/out/src/storage/remoting/StorageMobile.d.ts.map +1 -1
  188. package/out/src/storage/remoting/StorageMobile.js.map +1 -1
  189. package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
  190. package/out/src/storage/schema/KnexMigrations.js +12 -0
  191. package/out/src/storage/schema/KnexMigrations.js.map +1 -1
  192. package/out/src/utility/Format.d.ts +14 -0
  193. package/out/src/utility/Format.d.ts.map +1 -0
  194. package/out/src/utility/Format.js +167 -0
  195. package/out/src/utility/Format.js.map +1 -0
  196. package/out/src/utility/utilityHelpers.d.ts +1 -1
  197. package/out/src/utility/utilityHelpers.d.ts.map +1 -1
  198. package/out/src/utility/utilityHelpers.js +3 -3
  199. package/out/src/utility/utilityHelpers.js.map +1 -1
  200. package/out/test/Wallet/local/localWallet.man.test.js +12 -16
  201. package/out/test/Wallet/local/localWallet.man.test.js.map +1 -1
  202. package/out/test/Wallet/support/operations.man.test.js +105 -135
  203. package/out/test/Wallet/support/operations.man.test.js.map +1 -1
  204. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts +2 -0
  205. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.d.ts.map +1 -0
  206. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js +385 -0
  207. package/out/test/Wallet/support/reqErrorReview.2025.05.06.man.test.js.map +1 -0
  208. package/out/test/storage/KnexMigrations.test.js +1 -1
  209. package/out/test/storage/KnexMigrations.test.js.map +1 -1
  210. package/out/test/utils/TestUtilsWalletStorage.d.ts +5 -0
  211. package/out/test/utils/TestUtilsWalletStorage.d.ts.map +1 -1
  212. package/out/test/utils/TestUtilsWalletStorage.js +20 -0
  213. package/out/test/utils/TestUtilsWalletStorage.js.map +1 -1
  214. package/out/tsconfig.all.tsbuildinfo +1 -1
  215. package/package.json +2 -2
  216. package/src/Wallet.ts +25 -10
  217. package/src/monitor/Monitor.ts +6 -4
  218. package/src/monitor/tasks/TaskNewHeader.ts +1 -1
  219. package/src/monitor/tasks/TaskServiceCallHistory.ts +26 -0
  220. package/src/sdk/WalletServices.interfaces.ts +2 -0
  221. package/src/sdk/WalletStorage.interfaces.ts +21 -1
  222. package/src/services/ServiceCollection.ts +121 -0
  223. package/src/services/Services.ts +157 -71
  224. package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
  225. package/src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts +1 -1
  226. package/src/services/chaintracker/chaintracks/index.ts +1 -1
  227. package/src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts +490 -0
  228. package/src/services/chaintracker/chaintracks/util/dirtyHashes.ts +29 -0
  229. package/src/services/createDefaultWalletServicesOptions.ts +16 -1
  230. package/src/services/providers/ARC.ts +8 -6
  231. package/src/signer/methods/internalizeAction.ts +6 -16
  232. package/src/storage/StorageKnex.ts +25 -1
  233. package/src/storage/StorageProvider.ts +44 -32
  234. package/src/storage/WalletStorageManager.ts +1 -1
  235. package/src/storage/__test/StorageIdb.test.ts +1 -0
  236. package/src/storage/__test/adminStats.man.test.ts +2 -0
  237. package/src/storage/methods/createAction.ts +5 -3
  238. package/src/storage/methods/generateChange.ts +1 -54
  239. package/src/storage/methods/getBeefForTransaction.ts +10 -2
  240. package/src/storage/methods/internalizeAction.ts +23 -14
  241. package/src/storage/methods/processAction.ts +5 -2
  242. package/src/storage/methods/utils.Buffer.ts +33 -0
  243. package/src/storage/methods/utils.ts +56 -0
  244. package/src/storage/remoting/StorageClient.ts +2 -2
  245. package/src/storage/remoting/StorageMobile.ts +2 -2
  246. package/src/storage/schema/KnexMigrations.ts +13 -0
  247. package/src/utility/Format.ts +133 -0
  248. package/src/utility/utilityHelpers.ts +2 -2
  249. package/test/Wallet/local/localWallet.man.test.ts +13 -16
  250. package/test/Wallet/support/operations.man.test.ts +118 -123
  251. package/test/Wallet/support/reqErrorReview.2025.05.06.man.test.ts +359 -0
  252. package/test/storage/KnexMigrations.test.ts +1 -1
  253. package/test/utils/TestUtilsWalletStorage.ts +23 -0
  254. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +0 -1
  255. package/mobile/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +0 -1
  256. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.d.ts.map +0 -1
  257. package/out/src/services/chaintracker/chaintracks/BlockHeaderApi.js.map +0 -1
  258. /package/mobile/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.d.ts → Api/BlockHeaderApi.d.ts} +0 -0
  259. /package/mobile/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.js → Api/BlockHeaderApi.js} +0 -0
  260. /package/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.d.ts → Api/BlockHeaderApi.d.ts} +0 -0
  261. /package/out/src/services/chaintracker/chaintracks/{BlockHeaderApi.js → Api/BlockHeaderApi.js} +0 -0
  262. /package/src/services/chaintracker/chaintracks/{BlockHeaderApi.ts → Api/BlockHeaderApi.ts} +0 -0
@@ -0,0 +1,490 @@
1
+ import { validateAgainstDirtyHashes } from './dirtyHashes'
2
+ import { BigNumber, Hash, Utils } from '@bsv/sdk'
3
+
4
+ import { promises as fs } from 'fs'
5
+
6
+ import { asArray, asBuffer, asString } from '../../../../utility/utilityHelpers.buffer'
7
+ import { doubleSha256BE, doubleSha256LE } from '../../../../utility/utilityHelpers'
8
+ import { BaseBlockHeader, BlockHeader } from '../Api/BlockHeaderApi'
9
+ import { Chain } from '../../../../sdk/types'
10
+
11
+ /**
12
+ * Computes sha256 hash of file contents read as bytes with no encoding.
13
+ * @param filepath Full filepath to file.
14
+ * @param bufferSize Optional read buffer size to use. Defaults to 80,000 bytes.
15
+ * @returns `{hash, length}` where `hash` is base64 string form of file hash and `length` is file length in bytes.
16
+ */
17
+ export async function sha256HashOfBinaryFile(
18
+ filepath: string,
19
+ bufferSize = 80000
20
+ ): Promise<{ hash: string; length: number }> {
21
+ const file = await fs.open(filepath, 'r')
22
+ try {
23
+ let length = 0
24
+
25
+ const sha256 = new Hash.SHA256()
26
+ const readBuf = Buffer.alloc(bufferSize)
27
+
28
+ // eslint-disable-next-line no-constant-condition
29
+ while (true) {
30
+ const rr = await file.read(readBuf, 0, readBuf.length)
31
+ if (!rr.bytesRead) break
32
+ length += rr.bytesRead
33
+ sha256.update(asArray(rr.buffer))
34
+ }
35
+
36
+ return { hash: Utils.toBase64(sha256.digest()), length }
37
+ } finally {
38
+ await file.close()
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Validate headers contained in an array of bytes. The headers must be consecutive block headers, 80 bytes long,
44
+ * where the hash of each header equals the previousHash of the following header.
45
+ * @param buffer Buffer of headers to be validated.
46
+ * @param previousHash Expected previousHash of first header.
47
+ * @param offset Optional starting offset within `buffer`.
48
+ * @param count Optional number of headers to validate. Validates to end of buffer if missing.
49
+ * @returns Header hash of last header validated or previousHash if there where none.
50
+ */
51
+ export function validateBufferOfHeaders(buffer: number[], previousHash: string, offset = 0, count = -1): string {
52
+ if (count < 0) count = Math.floor((buffer.length - offset) / 80)
53
+ count = Math.max(0, count)
54
+ let lastHeaderHash = previousHash
55
+ for (let i = 0; i < count; i++) {
56
+ const headerStart = offset + i * 80
57
+ const headerEnd = headerStart + 80
58
+ if (headerEnd > buffer.length) {
59
+ throw {
60
+ message: `header ${i} missing bytes for header at offset ${headerStart} in buffer of length ${buffer.length}`
61
+ }
62
+ }
63
+ const header = buffer.slice(headerStart, headerEnd)
64
+ const hashPrev = asString(header.slice(4, 36).reverse())
65
+ if (lastHeaderHash !== hashPrev)
66
+ throw { message: `header ${i} invalid previousHash ${lastHeaderHash} vs ${hashPrev}` }
67
+ lastHeaderHash = asString(doubleSha256BE(header))
68
+ validateAgainstDirtyHashes(lastHeaderHash)
69
+ }
70
+ return lastHeaderHash
71
+ }
72
+
73
+ /**
74
+ * @param work chainWork as a BigNumber
75
+ * @returns Converted chainWork value from BN to hex string of 32 bytes.
76
+ */
77
+ export function workBNtoBuffer(work: BigNumber): string {
78
+ return work.toString(16).padStart(64, '0')
79
+ }
80
+
81
+ /**
82
+ * Returns true if work1 is more work (greater than) work2
83
+ */
84
+ export function isMoreWork(work1: string, work2: string): boolean {
85
+ return new BigNumber(asArray(work1), 16).gt(new BigNumber(asArray(work2), 16))
86
+ }
87
+
88
+ /**
89
+ * Add two Buffer encoded chainwork values
90
+ * @returns Sum of work1 + work2 as Buffer encoded chainWork value
91
+ */
92
+ export function addWork(work1: string, work2: string): string {
93
+ const sum = new BigNumber(asArray(work1), 16).add(new BigNumber(asArray(work2), 16))
94
+ return workBNtoBuffer(sum)
95
+ }
96
+
97
+ /**
98
+ * Subtract Buffer encoded chainwork values
99
+ * @returns work1 - work2 as Buffer encoded chainWork value
100
+ */
101
+ export function subWork(work1: string, work2: string): string {
102
+ const sum = new BigNumber(asArray(work1), 16).sub(new BigNumber(asArray(work2), 16))
103
+ return workBNtoBuffer(sum)
104
+ }
105
+
106
+ /**
107
+ * Computes "target" value for 4 byte Bitcoin block header "bits" value.
108
+ * @param bits number or converted from Buffer using `readUint32LE`
109
+ * @returns 32 byte Buffer with "target" value
110
+ */
111
+ export function convertBitsToTarget(bits: number | number[]): BigNumber {
112
+ if (Array.isArray(bits)) bits = readUInt32LE(bits, 0)
113
+
114
+ const shift = (bits >> 24) & 0xff
115
+ const data = bits & 0x007fffff
116
+
117
+ const target = new BigNumber(data)
118
+ if (shift <= 3) {
119
+ target.iushrn(8 * (3 - shift))
120
+ } else {
121
+ target.iushln(8 * (shift - 3))
122
+ }
123
+
124
+ return target
125
+ }
126
+
127
+ /**
128
+ * Computes "chainWork" value for 4 byte Bitcoin block header "bits" value.
129
+ * @param bits number or converted from Buffer using `readUint32LE`
130
+ * @returns 32 byte Buffer with "chainWork" value
131
+ */
132
+ export function convertBitsToWork(bits: number | number[]): string {
133
+ const target = convertBitsToTarget(bits)
134
+
135
+ // convert target to work
136
+ const work = target.notn(256).div(target.addn(1)).addn(1)
137
+
138
+ return work.toString(16).padStart(64, '0')
139
+ }
140
+
141
+ export function deserializeBaseBlockHeaders(
142
+ buffer: number[],
143
+ offset = 0,
144
+ count?: number | undefined
145
+ ): BaseBlockHeader[] {
146
+ const headers: BaseBlockHeader[] = []
147
+ while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {
148
+ headers.push(deserializeBlockHeader(buffer, offset))
149
+ offset += 80
150
+ }
151
+ return headers
152
+ }
153
+
154
+ export function deserializeBlockHeaders(
155
+ firstHeight: number,
156
+ buffer: number[],
157
+ offset = 0,
158
+ count?: number | undefined
159
+ ): BlockHeader[] {
160
+ const headers: BlockHeader[] = []
161
+ let nextHeight = firstHeight
162
+ while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {
163
+ const baseBuffer = buffer.slice(offset, offset + 80)
164
+ const base = deserializeBlockHeader(baseBuffer)
165
+ const header = {
166
+ ...base,
167
+ height: nextHeight++,
168
+ hash: asString(blockHash(baseBuffer))
169
+ }
170
+ headers.push(header)
171
+ offset += 80
172
+ }
173
+ return headers
174
+ }
175
+
176
+ /**
177
+ * Extract an array of block hashes and of merkleRoots from a buffer of serialized block headers.
178
+ * @param buffer
179
+ */
180
+ export function extractHashesAndRoots(buffer: Buffer): { hashes: Buffer[]; merkleRoots: Buffer[] } {
181
+ const hashes: Buffer[] = []
182
+ const merkleRoots: Buffer[] = []
183
+ for (let i = 0; i < buffer.length / 80; i++) {
184
+ const offset = i * 80
185
+ const hash = asBuffer(doubleSha256LE(asArray(buffer.subarray(offset, 80 + offset))).reverse())
186
+ const merkleRoot = buffer.subarray(36 + offset, 68 + offset).reverse()
187
+ hashes.push(hash)
188
+ merkleRoots.push(merkleRoot)
189
+ }
190
+ return { hashes, merkleRoots }
191
+ }
192
+
193
+ /**
194
+ * Given a block header, ensures that its format is correct. This does not
195
+ * check its difficulty or validity relative to the chain of headers.
196
+ *
197
+ * Throws on format errors.
198
+ *
199
+ * @param The header to validate
200
+ *
201
+ * @returns true if the header is correctly formatted
202
+ */
203
+ export function validateHeaderFormat(header: BlockHeader): void {
204
+ const ALLOWED_KEYS = {
205
+ version: true,
206
+ previousHash: true,
207
+ merkleRoot: true,
208
+ time: true,
209
+ bits: true,
210
+ nonce: true,
211
+ height: true,
212
+ hash: true
213
+ }
214
+
215
+ const UINT_MAX = 0xffffffff
216
+
217
+ /**
218
+ * Root object checks
219
+ */
220
+ if (typeof header === 'undefined') {
221
+ throw new Error('Missing header.')
222
+ }
223
+ if (typeof header !== 'object') {
224
+ throw new Error('Header must be an object.')
225
+ }
226
+ if (!Object.keys(header).every(key => ALLOWED_KEYS[key])) {
227
+ throw new Error('Header contains extra properties.')
228
+ }
229
+
230
+ /**
231
+ * Version
232
+ */
233
+ if (typeof header.version !== 'number') {
234
+ throw new Error('Header version must be a number.')
235
+ }
236
+ if (!Number.isInteger(header.version)) {
237
+ throw new Error('Header version must be an integer.')
238
+ }
239
+ if (header.version < 0 || header.version > UINT_MAX) {
240
+ throw new Error(`Header version must be between 0 and ${UINT_MAX}.`)
241
+ }
242
+
243
+ /**
244
+ * Height
245
+ */
246
+ if (typeof header.height !== 'number') {
247
+ throw new Error('Header height must be a number.')
248
+ }
249
+ if (!Number.isInteger(header.height)) {
250
+ throw new Error('Header height must be an integer.')
251
+ }
252
+ if (header.height < 0 || header.height > UINT_MAX / 2) {
253
+ throw new Error(`Header version must be between 0 and ${UINT_MAX / 2}.`)
254
+ }
255
+
256
+ /**
257
+ * Previous hash
258
+ */
259
+ if (header.previousHash.length !== 64) {
260
+ throw new Error('Header previousHash must be 32 hex bytes.')
261
+ }
262
+
263
+ /**
264
+ * Merkle root
265
+ */
266
+ if (header.merkleRoot.length !== 64) {
267
+ throw new Error('Header merkleRoot must be 32 hex bytes.')
268
+ }
269
+
270
+ /**
271
+ * Time
272
+ */
273
+ if (typeof header.time !== 'number') {
274
+ throw new Error('Header time must be a number.')
275
+ }
276
+ if (!Number.isInteger(header.time)) {
277
+ throw new Error('Header time must be an integer.')
278
+ }
279
+ if (header.time < 0 || header.time > UINT_MAX) {
280
+ throw new Error(`Header time must be between 0 and ${UINT_MAX}.`)
281
+ }
282
+
283
+ /**
284
+ * Bits
285
+ */
286
+ if (typeof header.bits !== 'number') {
287
+ throw new Error('Header bits must be a number.')
288
+ }
289
+ if (!Number.isInteger(header.bits)) {
290
+ throw new Error('Header bits must be an integer.')
291
+ }
292
+ if (header.bits < 0 || header.bits > UINT_MAX) {
293
+ throw new Error(`Header bits must be between 0 and ${UINT_MAX}.`)
294
+ }
295
+
296
+ /**
297
+ * Nonce
298
+ */
299
+ if (typeof header.nonce !== 'number') {
300
+ throw new Error('Header nonce must be a number.')
301
+ }
302
+ if (!Number.isInteger(header.nonce)) {
303
+ throw new Error('Header nonce must be an integer.')
304
+ }
305
+ if (header.nonce < 0 || header.nonce > UINT_MAX) {
306
+ throw new Error(`Header nonce must be between 0 and ${UINT_MAX}.`)
307
+ }
308
+
309
+ /**
310
+ * Hash
311
+ */
312
+ if (header.hash.length !== 64) {
313
+ throw new Error('Header hash must be 32 hex bytes.')
314
+ }
315
+ if (header.hash !== asString(blockHash(header))) {
316
+ throw new Error('Header hash is invalid.')
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Ensures that a header has a valid proof-of-work
322
+ * Requires chain is 'main'
323
+ *
324
+ * @param header The header to validate
325
+ *
326
+ * @returns true if the header is valid
327
+ */
328
+ export function validateHeaderDifficulty(hash: Buffer, bits: number) {
329
+ const hashBN = new BigNumber(asArray(hash))
330
+
331
+ const target = convertBitsToTarget(bits)
332
+
333
+ if (hashBN.lte(target)) return true
334
+
335
+ throw new Error('Block hash is not less than specified target.')
336
+ }
337
+
338
+ /**
339
+ * Computes double sha256 hash of bitcoin block header
340
+ * bytes are reversed to bigendian order
341
+ *
342
+ * If header is a Buffer, it is required to 80 bytes long
343
+ * and in standard block header serialized encoding.
344
+ *
345
+ * @returns doule sha256 hash of header bytes reversed
346
+ * @publicbody
347
+ */
348
+ export function blockHash(header: BaseBlockHeader | number[]): string {
349
+ const a = !Array.isArray(header) ? serializeBlockHeader(header) : header
350
+ if (a.length !== 80) throw new Error('Block header must be 80 bytes long.')
351
+ return asString(doubleSha256BE(a))
352
+ }
353
+
354
+ /**
355
+ * Serializes a block header as an 80 byte Buffer.
356
+ * The exact serialized format is defined in the Bitcoin White Paper
357
+ * such that computing a double sha256 hash of the buffer computes
358
+ * the block hash for the header.
359
+ * @returns 80 byte Buffer
360
+ * @publicbody
361
+ */
362
+ export function serializeBlockHeader(header: BaseBlockHeader, buffer?: number[], offset?: number): number[] {
363
+ const writer = new Utils.Writer()
364
+ writer.writeUInt32LE(header.version)
365
+ writer.write(asArray(header.previousHash).reverse())
366
+ writer.write(asArray(header.merkleRoot).reverse())
367
+ writer.writeUInt32LE(header.time)
368
+ writer.writeUInt32LE(header.bits)
369
+ writer.writeUInt32LE(header.nonce)
370
+ const data = writer.toArray()
371
+ if (buffer) {
372
+ offset ||= 0
373
+ buffer.splice(offset, buffer.length, ...data)
374
+ }
375
+ return data
376
+ }
377
+
378
+ /**
379
+ * Deserialize a block header from an 80 byte buffer
380
+ * @publicbody
381
+ */
382
+ export function deserializeBlockHeader(buffer: number[], offset = 0): BaseBlockHeader {
383
+ const reader = new Utils.Reader(buffer, offset)
384
+ const header: BaseBlockHeader = {
385
+ version: reader.readUInt32LE(),
386
+ previousHash: asString(reader.read(32).reverse()),
387
+ merkleRoot: asString(reader.read(32).reverse()),
388
+ time: reader.readUInt32LE(),
389
+ bits: reader.readUInt32LE(),
390
+ nonce: reader.readUInt32LE()
391
+ }
392
+ return header
393
+ }
394
+
395
+ /**
396
+ * Returns the genesis block for the specified chain.
397
+ * @publicbody
398
+ */
399
+ export function genesisHeader(chain: Chain): BlockHeader {
400
+ return chain === 'main'
401
+ ? {
402
+ version: 1,
403
+ previousHash: '0000000000000000000000000000000000000000000000000000000000000000',
404
+ merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
405
+ time: 1231006505,
406
+ bits: 486604799,
407
+ nonce: 2083236893,
408
+ height: 0,
409
+ hash: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
410
+ }
411
+ : {
412
+ version: 1,
413
+ previousHash: '0000000000000000000000000000000000000000000000000000000000000000',
414
+ merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
415
+ time: 1296688602,
416
+ bits: 486604799,
417
+ nonce: 414098458,
418
+ height: 0,
419
+ hash: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Returns the genesis block for the specified chain.
425
+ * @publicbody
426
+ */
427
+ export function genesisBuffer(chain: Chain): number[] {
428
+ return serializeBlockHeader(genesisHeader(chain))
429
+ }
430
+
431
+ /**
432
+ * Returns a copy of a Buffer with byte order reversed.
433
+ * @returns new buffer with byte order reversed.
434
+ * @publicbody
435
+ */
436
+ export function swapByteOrder(buffer: number[]): number[] {
437
+ return buffer.slice().reverse()
438
+ }
439
+
440
+ /**
441
+ * @param num a number value in the Uint32 value range
442
+ * @param littleEndian true for little-endian byte order in Buffer
443
+ * @returns four byte buffer with Uint32 number encoded
444
+ * @publicbody
445
+ */
446
+ export function convertUint32ToBuffer(n: number, littleEndian = true): number[] {
447
+ const a = [
448
+ n & 0xff, // lowest byte
449
+ (n >> 8) & 0xff,
450
+ (n >> 16) & 0xff,
451
+ (n >> 24) & 0xff // highest byte
452
+ ]
453
+ return littleEndian ? a : a.reverse()
454
+ }
455
+
456
+ export function writeUInt32LE(n: number, a: number[], offset: number): number {
457
+ a[offset++] = n & 0xff // lowest byte
458
+ a[offset++] = (n >> 8) & 0xff
459
+ a[offset++] = (n >> 16) & 0xff
460
+ a[offset++] = (n >> 24) & 0xff // highest byte
461
+ return offset
462
+ }
463
+
464
+ export function writeUInt32BE(n: number, a: number[], offset: number): number {
465
+ a[offset++] = (n >> 24) & 0xff // highest byte
466
+ a[offset++] = (n >> 16) & 0xff
467
+ a[offset++] = (n >> 8) & 0xff
468
+ a[offset++] = n & 0xff // lowest byte
469
+ return offset
470
+ }
471
+
472
+ export function readUInt32LE(a: number[], offset: number): number {
473
+ return a[offset++] | (a[offset++] << 8) | (a[offset++] << 16) | (a[offset++] << 24)
474
+ }
475
+
476
+ export function readUInt32BE(a: number[], offset: number): number {
477
+ return (a[offset++] << 24) | (a[offset++] << 16) | (a[offset++] << 8) | a[offset++]
478
+ }
479
+
480
+ /**
481
+ * @param buffer four byte buffer with Uint32 number encoded
482
+ * @param littleEndian true for little-endian byte order in Buffer
483
+ * @returns a number value in the Uint32 value range
484
+ * @publicbody
485
+ */
486
+ export function convertBufferToUint32(buffer: number[], littleEndian = true): number {
487
+ const a = littleEndian ? buffer : buffer.slice().reverse()
488
+ const n = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)
489
+ return n
490
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * These hashes are for blocks that are to known to have violated the Bitcoin
3
+ * protocol. Regardless of the amount of proof-of-work that chains built on top
4
+ * of them may have accumulated, they cannot be considered valid Bitcoin blocks.
5
+ *
6
+ * In the first instance, segregating witness data from transactions is not
7
+ * part of the design of Bitcoin.
8
+ *
9
+ * In the second instance, adding new opcodes to be used when evaluating
10
+ * scripts is also not allowed.
11
+ */
12
+ export const dirtyHashes = {
13
+ // Block 478,558 with hash of 0000000000000000011865af4122fe3b144e2cbeea86142e8ff2fb4107352d43 was the last block shared by BSV, BCH and BTC
14
+ // Block 478,559 with hash of 00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148 was the first block of the BTC Segwit chain.
15
+ // Block 478,559 with hash of 000000000000000000651ef99cb9fcbe0dadde1d424bd9f15ff20136191a5eec was the valid Bitcoin block shared by BSV and BCH.
16
+ '00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148':
17
+ 'This is the first header of the invalid SegWit chain.',
18
+ '0000000000000000004626ff6e3b936941d341c5932ece4357eeccac44e6d56c':
19
+ 'This is the first header of the invalid ABC chain.'
20
+ }
21
+
22
+ /**
23
+ * Throws Error if blockHash is in the dirtyHashes list.
24
+ */
25
+ export function validateAgainstDirtyHashes(blockHash: string): void {
26
+ if (dirtyHashes[blockHash]) {
27
+ throw new Error(`Not adding a header with a dirty hash: ${dirtyHashes[blockHash]}`)
28
+ }
29
+ }
@@ -2,10 +2,15 @@ import { randomBytesHex, sdk } from '../index.client'
2
2
  import { ChaintracksServiceClient } from './chaintracker'
3
3
 
4
4
  export function createDefaultWalletServicesOptions(chain: sdk.Chain): sdk.WalletServicesOptions {
5
+ const deploymentId = `wallet-toolbox-${randomBytesHex(16)}`
5
6
  const taalApiKey =
6
7
  chain === 'main'
7
8
  ? 'mainnet_9596de07e92300c6287e4393594ae39c' // no plan
8
9
  : 'testnet_0e6cf72133b43ea2d7861da2a38684e3' // personal "starter" key
10
+ const gorillaPoolApiKey =
11
+ chain === 'main'
12
+ ? ''
13
+ : ''
9
14
 
10
15
  const o: sdk.WalletServicesOptions = {
11
16
  chain,
@@ -36,7 +41,12 @@ export function createDefaultWalletServicesOptions(chain: sdk.Chain): sdk.Wallet
36
41
  arcUrl: arcDefaultUrl(chain),
37
42
  arcConfig: {
38
43
  apiKey: taalApiKey,
39
- deploymentId: `wallet-toolbox-${randomBytesHex(16)}`
44
+ deploymentId
45
+ },
46
+ arcGorillaPoolUrl: arcGorillaPoolUrl(chain),
47
+ arcGorillaPoolConfig: {
48
+ apiKey: gorillaPoolApiKey,
49
+ deploymentId
40
50
  }
41
51
  }
42
52
  return o
@@ -46,3 +56,8 @@ export function arcDefaultUrl(chain: sdk.Chain): string {
46
56
  const url = chain === 'main' ? 'https://arc.taal.com' : 'https://arc-test.taal.com'
47
57
  return url
48
58
  }
59
+
60
+ export function arcGorillaPoolUrl(chain: sdk.Chain): string | undefined {
61
+ const url = chain === 'main' ? 'https://arc.gorillapool.io' : undefined
62
+ return url
63
+ }
@@ -36,6 +36,7 @@ function defaultDeploymentId(): string {
36
36
  * Represents an ARC transaction broadcaster.
37
37
  */
38
38
  export class ARC {
39
+ readonly name: string
39
40
  readonly URL: string
40
41
  readonly apiKey: string | undefined
41
42
  readonly deploymentId: string
@@ -50,16 +51,17 @@ export class ARC {
50
51
  * @param {string} URL - The URL endpoint for the ARC API.
51
52
  * @param {ArcConfig} config - Configuration options for the ARC broadcaster.
52
53
  */
53
- constructor(URL: string, config?: ArcConfig)
54
+ constructor(URL: string, config?: ArcConfig, name?: string)
54
55
  /**
55
56
  * Constructs an instance of the ARC broadcaster.
56
57
  *
57
58
  * @param {string} URL - The URL endpoint for the ARC API.
58
59
  * @param {string} apiKey - The API key used for authorization with the ARC API.
59
60
  */
60
- constructor(URL: string, apiKey?: string)
61
+ constructor(URL: string, apiKey?: string, name?: string)
61
62
 
62
- constructor(URL: string, config?: string | ArcConfig) {
63
+ constructor(URL: string, config?: string | ArcConfig, name?: string) {
64
+ this.name = name ?? 'ARC'
63
65
  this.URL = URL
64
66
  if (typeof config === 'string') {
65
67
  this.apiKey = config
@@ -143,7 +145,7 @@ export class ARC {
143
145
  }
144
146
 
145
147
  const url = `${this.URL}/v1/tx`
146
- const nn = () => ({ name: 'ARCv1tx', when: new Date().toISOString() })
148
+ const nn = () => ({ name: this.name, when: new Date().toISOString() })
147
149
  const nne = () => ({ ...nn(), rawTx, txids: txids.join(','), url })
148
150
 
149
151
  try {
@@ -241,13 +243,13 @@ export class ARC {
241
243
  */
242
244
  async postBeef(beef: Beef, txids: string[]): Promise<sdk.PostBeefResult> {
243
245
  const r: sdk.PostBeefResult = {
244
- name: 'ARC',
246
+ name: this.name,
245
247
  status: 'success',
246
248
  txidResults: [],
247
249
  notes: []
248
250
  }
249
251
 
250
- const nn = () => ({ name: 'ARCpostBeef', when: new Date().toISOString() })
252
+ const nn = () => ({ name: this.name, when: new Date().toISOString() })
251
253
 
252
254
  if (beef.version === BEEF_V2 && beef.txs.every(btx => !btx.isTxidOnly)) {
253
255
  beef.version = BEEF_V1
@@ -39,7 +39,7 @@ export async function internalizeAction(
39
39
  wallet: Wallet,
40
40
  auth: sdk.AuthId,
41
41
  args: InternalizeActionArgs
42
- ): Promise<InternalizeActionResult> {
42
+ ): Promise<sdk.StorageInternalizeActionResult> {
43
43
  const vargs = sdk.validateInternalizeActionArgs(args)
44
44
 
45
45
  const { ab, tx, txid } = await validateAtomicBeef()
@@ -60,7 +60,7 @@ export async function internalizeAction(
60
60
  }
61
61
  }
62
62
 
63
- const r: InternalizeActionResult = await wallet.storage.internalizeAction(args)
63
+ const r: sdk.StorageInternalizeActionResult = await wallet.storage.internalizeAction(args)
64
64
 
65
65
  return r
66
66
 
@@ -89,25 +89,15 @@ export async function internalizeAction(
89
89
  // TODO: Add support for known txids...
90
90
 
91
91
  const txValid = await ab.verify(await wallet.getServices().getChainTracker(), false)
92
- if (!txValid || !ab.atomicTxid) throw new sdk.WERR_INVALID_PARAMETER('tx', 'valid AtomicBEEF')
92
+ if (!txValid || !ab.atomicTxid) {
93
+ console.log(`internalizeAction beef is invalid: ${ab.toLogString()}`)
94
+ throw new sdk.WERR_INVALID_PARAMETER('tx', 'valid AtomicBEEF')
95
+ }
93
96
  const txid = ab.atomicTxid
94
97
  const btx = ab.findTxid(txid)
95
98
  if (!btx) throw new sdk.WERR_INVALID_PARAMETER('tx', `valid AtomicBEEF with newest txid of ${txid}`)
96
99
  const tx = btx.tx!
97
100
 
98
- /*
99
- for (const i of tx.inputs) {
100
- if (!i.sourceTXID)
101
- throw new sdk.WERR_INTERNAL('beef Transactions must have sourceTXIDs')
102
- if (!i.sourceTransaction) {
103
- const btx = ab.findTxid(i.sourceTXID)
104
- if (!btx)
105
- throw new sdk.WERR_INVALID_PARAMETER('tx', `valid AtomicBEEF and contain input transaction with txid ${i.sourceTXID}`);
106
- i.sourceTransaction = btx.tx
107
- }
108
- }
109
- */
110
-
111
101
  return { ab, tx, txid }
112
102
  }
113
103
  }
@@ -488,6 +488,27 @@ export class StorageKnex extends StorageProvider implements sdk.WalletStoragePro
488
488
  let q = this.toDb(args.trx)<T>(table)
489
489
  if (args.partial && Object.keys(args.partial).length > 0) q.where(args.partial)
490
490
  if (args.since) q.where('updated_at', '>=', this.validateDateForWhere(args.since))
491
+ if (args.orderDescending) {
492
+ let sortColumn = ''
493
+ switch (table) {
494
+ case 'certificates': sortColumn = 'certificateId'; break
495
+ case 'commissions': sortColumn = 'commissionId'; break
496
+ case 'output_baskets': sortColumn = 'basketId'; break
497
+ case 'outputs': sortColumn = 'outputId'; break
498
+ case 'output_tags': sortColumn = 'outputTagId'; break
499
+ case 'proven_tx_reqs': sortColumn = 'provenTxReqId'; break
500
+ case 'proven_txs': sortColumn = 'provenTxId'; break
501
+ case 'sync_states': sortColumn = 'syncStateId'; break
502
+ case 'transactions': sortColumn = 'transactionId'; break
503
+ case 'tx_labels': sortColumn = 'txLabelId'; break
504
+ case 'users': sortColumn = 'userId'; break
505
+ case 'monitor_events': sortColumn = 'id'; break
506
+ default: break;
507
+ }
508
+ if (sortColumn !== '') {
509
+ q.orderBy(sortColumn, 'desc')
510
+ }
511
+ }
491
512
  if (args.paged) {
492
513
  q.limit(args.paged.limit)
493
514
  q.offset(args.paged.offset || 0)
@@ -554,7 +575,10 @@ export class StorageKnex extends StorageProvider implements sdk.WalletStoragePro
554
575
  )
555
576
  const q = this.setupQuery('proven_tx_reqs', args)
556
577
  if (args.status && args.status.length > 0) q.whereIn('status', args.status)
557
- if (args.txids && args.txids.length > 0) q.whereIn('txid', args.txids)
578
+ if (args.txids) {
579
+ const txids = args.txids.filter(txid => txid !== undefined)
580
+ if (txids.length > 0) q.whereIn('txid', txids)
581
+ }
558
582
  return q
559
583
  }
560
584
  findProvenTxsQuery(args: sdk.FindProvenTxsArgs): Knex.QueryBuilder {