@bsv/wallet-toolbox 1.3.24 → 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 (112) hide show
  1. package/mobile/out/src/monitor/Monitor.d.ts.map +1 -1
  2. package/mobile/out/src/monitor/Monitor.js +4 -0
  3. package/mobile/out/src/monitor/Monitor.js.map +1 -1
  4. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
  5. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
  6. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
  7. package/mobile/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
  8. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
  9. package/mobile/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
  10. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts +5 -0
  11. package/mobile/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
  12. package/mobile/out/src/services/ServiceCollection.d.ts +38 -0
  13. package/mobile/out/src/services/ServiceCollection.d.ts.map +1 -1
  14. package/mobile/out/src/services/ServiceCollection.js +85 -0
  15. package/mobile/out/src/services/ServiceCollection.js.map +1 -1
  16. package/mobile/out/src/services/Services.d.ts +11 -2
  17. package/mobile/out/src/services/Services.d.ts.map +1 -1
  18. package/mobile/out/src/services/Services.js +159 -68
  19. package/mobile/out/src/services/Services.js.map +1 -1
  20. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
  21. package/mobile/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  22. package/mobile/out/src/services/createDefaultWalletServicesOptions.js +15 -1
  23. package/mobile/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  24. package/mobile/out/src/services/providers/ARC.d.ts +3 -2
  25. package/mobile/out/src/services/providers/ARC.d.ts.map +1 -1
  26. package/mobile/out/src/services/providers/ARC.js +5 -4
  27. package/mobile/out/src/services/providers/ARC.js.map +1 -1
  28. package/mobile/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
  29. package/mobile/out/src/signer/methods/internalizeAction.js +3 -13
  30. package/mobile/out/src/signer/methods/internalizeAction.js.map +1 -1
  31. package/mobile/out/src/storage/StorageProvider.js +1 -1
  32. package/mobile/out/src/storage/StorageProvider.js.map +1 -1
  33. package/mobile/out/src/storage/methods/createAction.d.ts.map +1 -1
  34. package/mobile/out/src/storage/methods/createAction.js +5 -1
  35. package/mobile/out/src/storage/methods/createAction.js.map +1 -1
  36. package/mobile/out/src/storage/methods/internalizeAction.js +2 -1
  37. package/mobile/out/src/storage/methods/internalizeAction.js.map +1 -1
  38. package/mobile/package-lock.json +7 -6
  39. package/mobile/package.json +2 -2
  40. package/out/src/monitor/Monitor.d.ts.map +1 -1
  41. package/out/src/monitor/Monitor.js +4 -0
  42. package/out/src/monitor/Monitor.js.map +1 -1
  43. package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts +12 -0
  44. package/out/src/monitor/tasks/TaskServiceCallHistory.d.ts.map +1 -0
  45. package/out/src/monitor/tasks/TaskServiceCallHistory.js +23 -0
  46. package/out/src/monitor/tasks/TaskServiceCallHistory.js.map +1 -0
  47. package/out/src/sdk/WalletServices.interfaces.d.ts +2 -0
  48. package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
  49. package/out/src/sdk/WalletStorage.interfaces.d.ts +5 -0
  50. package/out/src/sdk/WalletStorage.interfaces.d.ts.map +1 -1
  51. package/out/src/services/ServiceCollection.d.ts +38 -0
  52. package/out/src/services/ServiceCollection.d.ts.map +1 -1
  53. package/out/src/services/ServiceCollection.js +85 -0
  54. package/out/src/services/ServiceCollection.js.map +1 -1
  55. package/out/src/services/Services.d.ts +11 -2
  56. package/out/src/services/Services.d.ts.map +1 -1
  57. package/out/src/services/Services.js +159 -68
  58. package/out/src/services/Services.js.map +1 -1
  59. package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts +2 -0
  60. package/out/src/services/__tests/ArcGorillaPool.man.test.d.ts.map +1 -0
  61. package/out/src/services/__tests/ArcGorillaPool.man.test.js +93 -0
  62. package/out/src/services/__tests/ArcGorillaPool.man.test.js.map +1 -0
  63. package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
  64. package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  65. package/out/src/services/createDefaultWalletServicesOptions.js +15 -1
  66. package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  67. package/out/src/services/providers/ARC.d.ts +3 -2
  68. package/out/src/services/providers/ARC.d.ts.map +1 -1
  69. package/out/src/services/providers/ARC.js +5 -4
  70. package/out/src/services/providers/ARC.js.map +1 -1
  71. package/out/src/signer/methods/internalizeAction.d.ts.map +1 -1
  72. package/out/src/signer/methods/internalizeAction.js +3 -13
  73. package/out/src/signer/methods/internalizeAction.js.map +1 -1
  74. package/out/src/storage/StorageKnex.d.ts.map +1 -1
  75. package/out/src/storage/StorageKnex.js +50 -2
  76. package/out/src/storage/StorageKnex.js.map +1 -1
  77. package/out/src/storage/StorageProvider.js +1 -1
  78. package/out/src/storage/StorageProvider.js.map +1 -1
  79. package/out/src/storage/methods/createAction.d.ts.map +1 -1
  80. package/out/src/storage/methods/createAction.js +5 -1
  81. package/out/src/storage/methods/createAction.js.map +1 -1
  82. package/out/src/storage/methods/internalizeAction.js +2 -1
  83. package/out/src/storage/methods/internalizeAction.js.map +1 -1
  84. package/out/src/storage/schema/KnexMigrations.d.ts.map +1 -1
  85. package/out/src/storage/schema/KnexMigrations.js +12 -0
  86. package/out/src/storage/schema/KnexMigrations.js.map +1 -1
  87. package/out/test/Wallet/local/localWallet.man.test.js +12 -16
  88. package/out/test/Wallet/local/localWallet.man.test.js.map +1 -1
  89. package/out/test/Wallet/support/operations.man.test.js +96 -6
  90. package/out/test/Wallet/support/operations.man.test.js.map +1 -1
  91. package/out/test/storage/KnexMigrations.test.js +1 -1
  92. package/out/test/storage/KnexMigrations.test.js.map +1 -1
  93. package/out/tsconfig.all.tsbuildinfo +1 -1
  94. package/package.json +2 -2
  95. package/src/monitor/Monitor.ts +4 -0
  96. package/src/monitor/tasks/TaskServiceCallHistory.ts +26 -0
  97. package/src/sdk/WalletServices.interfaces.ts +2 -0
  98. package/src/sdk/WalletStorage.interfaces.ts +5 -0
  99. package/src/services/ServiceCollection.ts +121 -0
  100. package/src/services/Services.ts +157 -71
  101. package/src/services/__tests/ArcGorillaPool.man.test.ts +108 -0
  102. package/src/services/createDefaultWalletServicesOptions.ts +16 -1
  103. package/src/services/providers/ARC.ts +8 -6
  104. package/src/signer/methods/internalizeAction.ts +4 -14
  105. package/src/storage/StorageKnex.ts +25 -1
  106. package/src/storage/StorageProvider.ts +1 -1
  107. package/src/storage/methods/createAction.ts +5 -3
  108. package/src/storage/methods/internalizeAction.ts +2 -1
  109. package/src/storage/schema/KnexMigrations.ts +13 -0
  110. package/test/Wallet/local/localWallet.man.test.ts +13 -16
  111. package/test/Wallet/support/operations.man.test.ts +107 -7
  112. package/test/storage/KnexMigrations.test.ts +1 -1
@@ -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
@@ -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 {
@@ -417,7 +417,7 @@ export abstract class StorageProvider extends StorageReaderWriter implements sdk
417
417
  requiredLevels?: number
418
418
  ): Promise<Beef> {
419
419
  const beef = await this.getValidBeefForTxid(txid, mergeToBeef, trustSelf, knownTxids, trx, requiredLevels)
420
- if (!beef) throw new sdk.WERR_INVALID_PARAMETER('txid', `${txid} is not known to storage.`)
420
+ if (!beef) throw new sdk.WERR_INVALID_PARAMETER('txid', `known to storage. ${txid} is not known.`)
421
421
  return beef
422
422
  }
423
423
 
@@ -18,8 +18,6 @@ import {
18
18
  randomBytesBase64,
19
19
  sdk,
20
20
  sha256Hash,
21
- stampLog,
22
- stampLogFormat,
23
21
  StorageProvider,
24
22
  TableOutput,
25
23
  TableOutputBasket,
@@ -552,7 +550,8 @@ async function validateRequiredInputs(
552
550
  ...input,
553
551
  vin,
554
552
  satoshis: -1,
555
- lockingScript: new Script()
553
+ lockingScript: new Script(),
554
+ output: undefined
556
555
  }))
557
556
 
558
557
  const trustSelf = vargs.options.trustSelf === 'known'
@@ -603,6 +602,9 @@ async function validateRequiredInputs(
603
602
  const { txid, vout } = input.outpoint
604
603
  const output = verifyOneOrNone(await storage.findOutputs({ partial: { userId, txid, vout } }))
605
604
  if (output) {
605
+ if (output.change) {
606
+ throw new sdk.WERR_INVALID_PARAMETER(`inputs[${input.vin}]`, 'an unmanaged input. Change outputs are managed by your wallet.')
607
+ }
606
608
  input.output = output
607
609
  if (!Array.isArray(output.lockingScript) || !Number.isInteger(output.satoshis))
608
610
  throw new sdk.WERR_INVALID_PARAMETER(`${txid}.${vout}`, 'output with valid lockingScript and satoshis')
@@ -347,7 +347,7 @@ class InternalizeActionContext {
347
347
  // make sure storage pursues getting a proof for it.
348
348
  const newReq = EntityProvenTxReq.fromTxid(this.txid, this.tx.toBinary(), this.args.tx)
349
349
  // this status is only relevant if the transaction is new to storage.
350
- newReq.status = 'unprocessed'
350
+ newReq.status = 'unsent'
351
351
  // this history and notify will be merged into an existing req if it exists.
352
352
  newReq.addHistoryNote({ what: 'internalizeAction', userId: this.userId })
353
353
  newReq.addNotifyTransactionId(transactionId)
@@ -357,6 +357,7 @@ class InternalizeActionContext {
357
357
  // This storage doesn't know about this txid yet.
358
358
 
359
359
  // TODO Can we immediately prove this txid?
360
+ // TODO Do full validation on the transaction?
360
361
 
361
362
  // Attempt to broadcast it to the network, throwing an error if it fails.
362
363
 
@@ -70,6 +70,19 @@ export class KnexMigrations implements MigrationSource<string> {
70
70
  }
71
71
  }
72
72
 
73
+ migrations['2025-05-13-001 add monitor events event index'] = {
74
+ async up(knex) {
75
+ await knex.schema.alterTable('monitor_events', table => {
76
+ table.index('event')
77
+ })
78
+ },
79
+ async down(knex) {
80
+ await knex.schema.alterTable('monitor_events', table => {
81
+ table.dropIndex('event')
82
+ })
83
+ }
84
+ }
85
+
73
86
  migrations['2025-03-03-001 descriptions to 2000'] = {
74
87
  async up(knex) {
75
88
  await knex.schema.alterTable('transactions', table => {
@@ -6,7 +6,7 @@ import { createOneSatTestOutput, createSetup, LocalWalletTestOptions } from '../
6
6
  const chain: sdk.Chain = 'test'
7
7
 
8
8
  const options: LocalWalletTestOptions = {
9
- setActiveClient: true,
9
+ setActiveClient: false,
10
10
  useMySQLConnectionForClient: true,
11
11
  useTestIdentityKey: true,
12
12
  useIdentityKey2: false
@@ -26,6 +26,18 @@ describe('localWallet tests', () => {
26
26
  await setup.wallet.destroy()
27
27
  })
28
28
 
29
+ test('0a monitor runOnce call history', async () => {
30
+ const setup = await createSetup(chain, options)
31
+ const key = await setup.wallet.getPublicKey({ identityKey: true })
32
+ expect(key.publicKey.toString()).toBe(setup.identityKey)
33
+ await setup.services.getRawTx('6dd8e416dfaf14c04899ccad2bf76a67c1d5598fece25cf4dcb7a076012b7d8d')
34
+ await setup.services.getRawTx('ac9cced61e2491be55061ce6577e0c59b909922ba92d5cc1cd754b10d721ab0e')
35
+ await setup.services.getRawTx('0000e416dfaf14c04899ccad2bf76a67c1d5598fece25cf4dcb7a076012b7d8d')
36
+ await setup.services.getRawTx('0000ced61e2491be55061ce6577e0c59b909922ba92d5cc1cd754b10d721ab0e')
37
+ await setup.monitor.runOnce()
38
+ await setup.wallet.destroy()
39
+ })
40
+
29
41
  test('2 create 1 sat delayed', async () => {
30
42
  const setup = await createSetup(chain, options)
31
43
  const car = await createOneSatTestOutput(setup, {}, 1)
@@ -58,21 +70,6 @@ describe('localWallet tests', () => {
58
70
  await setup.wallet.destroy()
59
71
  })
60
72
 
61
- test('4 review change utxos', async () => {
62
- const setup = await createSetup(chain, options)
63
- const lor = await setup.wallet.listOutputs({
64
- basket: specOpInvalidChange
65
- })
66
- if (lor.totalOutputs > 0) {
67
- debugger
68
- const lor = await setup.wallet.listOutputs({
69
- basket: specOpInvalidChange,
70
- tags: ['release']
71
- })
72
- }
73
- await setup.wallet.destroy()
74
- })
75
-
76
73
  test('5 review synchunk', async () => {
77
74
  const setup = await createSetup(chain, options)
78
75
  const identityKey = setup.identityKey
@@ -1,16 +1,17 @@
1
- import { WalletOutput } from '@bsv/sdk'
1
+ import { Beef, MerklePath, WalletOutput } from '@bsv/sdk'
2
2
  import { sdk, TableOutput, TableUser, verifyOne, verifyOneOrNone } from '../../../src'
3
- import { _tu } from '../../utils/TestUtilsWalletStorage'
3
+ import { _tu, logger } from '../../utils/TestUtilsWalletStorage'
4
4
  import { specOpInvalidChange, ValidListOutputsArgs } from '../../../src/sdk'
5
5
  import { LocalWalletTestOptions } from '../../utils/localWalletMethods'
6
6
  import { Format } from '../../../src/utility/Format'
7
+ import { asString } from '../../../src/utility/utilityHelpers.noBuffer'
7
8
 
8
9
  describe('operations.man tests', () => {
9
10
  jest.setTimeout(99999999)
10
11
 
11
12
  test('0 review and release all production invalid change utxos', async () => {
12
13
  const { env, storage } = await _tu.createMainReviewSetup()
13
- const users = await storage.findUsers({ partial: {} })
14
+ const users = await storage.findUsers({ partial: { } })
14
15
  const withInvalid: Record<number, { user: TableUser; outputs: WalletOutput[]; total: number }> = {}
15
16
  const vargs: ValidListOutputsArgs = {
16
17
  basket: specOpInvalidChange,
@@ -48,13 +49,14 @@ describe('operations.man tests', () => {
48
49
 
49
50
  test('1 review and unfail false doubleSpends', async () => {
50
51
  const { env, storage, services } = await _tu.createMainReviewSetup()
51
- let offset = 2700
52
+ let offset = 0
52
53
  const limit = 100
53
54
  let allUnfails: number[] = []
54
55
  for (;;) {
55
56
  let log = ''
56
57
  const unfails: number[] = []
57
- const reqs = await storage.findProvenTxReqs({ partial: { status: 'doubleSpend' }, paged: { limit, offset } })
58
+ debugger;
59
+ const reqs = await storage.findProvenTxReqs({ partial: { status: 'doubleSpend' }, paged: { limit, offset }, orderDescending: true })
58
60
  for (const req of reqs) {
59
61
  const gsr = await services.getStatusForTxids([req.txid])
60
62
  if (gsr.results[0].status !== 'unknown') {
@@ -75,13 +77,13 @@ describe('operations.man tests', () => {
75
77
 
76
78
  test('2 review and unfail false invalids', async () => {
77
79
  const { env, storage, services } = await _tu.createMainReviewSetup()
78
- let offset = 800
80
+ let offset = 0
79
81
  const limit = 100
80
82
  let allUnfails: number[] = []
81
83
  for (;;) {
82
84
  let log = ''
83
85
  const unfails: number[] = []
84
- const reqs = await storage.findProvenTxReqs({ partial: { status: 'invalid' }, paged: { limit, offset } })
86
+ const reqs = await storage.findProvenTxReqs({ partial: { status: 'invalid' }, paged: { limit, offset }, orderDescending: true })
85
87
  for (const req of reqs) {
86
88
  if (!req.txid || !req.rawTx) continue
87
89
  const gsr = await services.getStatusForTxids([req.txid])
@@ -101,6 +103,51 @@ describe('operations.man tests', () => {
101
103
  await storage.destroy()
102
104
  })
103
105
 
106
+ test.skip('3 review proven_txs', async () => {
107
+ const { env, storage, services } = await _tu.createMainReviewSetup()
108
+ let offset = 0
109
+ const limit = 100
110
+ let allUnfails: number[] = []
111
+ //for (const provenTxId of [3064, 3065, 11268, 11269, 11270, 11271] ) {
112
+ for (let height = 895000; height < 895026; height++) {
113
+ let log = ''
114
+ const unfails: number[] = []
115
+ const txs = await storage.findProvenTxs({ partial: { height }, paged: { limit, offset } })
116
+ for (const tx of txs) {
117
+ const gmpr = await services.getMerklePath(tx.txid)
118
+ if (gmpr && gmpr.header && gmpr.merklePath) {
119
+ const mp = gmpr.merklePath
120
+ const h = gmpr.header
121
+ const mr = mp.computeRoot(tx.txid)
122
+ const index = mp.path[0].find(leaf => leaf.hash === tx.txid)?.offset!
123
+
124
+ const mp2 = MerklePath.fromBinary(tx.merklePath)
125
+ const mr2 = mp2.computeRoot()
126
+
127
+ if (h.height !== mp.blockHeight || h.merkleRoot !== mr) {
128
+ console.log(`Merkle root mismatch for ${tx.txid} ${h.merkleRoot} != ${mr}`)
129
+ } else {
130
+ if (tx.merkleRoot !== mr || tx.height !== mp.blockHeight || tx.blockHash !== h.hash || tx.index !== index || mp2.blockHeight !== tx.height || mr2 !== tx.merkleRoot || asString(tx.merklePath) !== asString(mp.toBinary())) {
131
+ debugger;
132
+ await storage.updateProvenTx(tx.provenTxId, {
133
+ merklePath: mp.toBinary(),
134
+ merkleRoot: mr,
135
+ height: mp.blockHeight,
136
+ blockHash: h.hash,
137
+ index
138
+ })
139
+ log += `updated ${tx.provenTxId}\n`
140
+ }
141
+ }
142
+ }
143
+ }
144
+ //console.log(`${offset} ${log}`)
145
+ //if (txs.length < limit) break
146
+ //offset += txs.length
147
+ }
148
+ await storage.destroy()
149
+ })
150
+
104
151
  test.skip('10 re-internalize failed WUI exports', async () => {
105
152
  const { env, storage, services } = await _tu.createMainReviewSetup()
106
153
  // From this user
@@ -174,4 +221,57 @@ describe('operations.man tests', () => {
174
221
  })
175
222
  await storage.destroy()
176
223
  })
224
+
225
+ test.skip('12 check storage merged BEEF', async () => {
226
+ const userId = 127
227
+ const txid = 'efba8b92a22c3308f432b292b5ec7efb3869ecd50c62cb3ddfb83871bc7be194'
228
+ const vout = 1
229
+ const { env, storage, services } = await _tu.createMainReviewSetup()
230
+
231
+ const ptx = verifyOne(await storage.findProvenTxs({ partial: { txid } }))
232
+
233
+ const mp = MerklePath.fromBinary(ptx.merklePath)
234
+ expect(mp.blockHeight).toBe(ptx.height)
235
+
236
+ const txids = ['24b19a5179c1f146e825643df4c6dc2ba21674828c20fc2948e105cb1ca91eae']
237
+
238
+ const r = await storage.getReqsAndBeefToShareWithWorld(txids, [])
239
+
240
+ await storage.destroy()
241
+ })
242
+
243
+ test('13 review use of outputs in all following transactions', async () => {
244
+ const { env, storage, services } = await _tu.createMainReviewSetup()
245
+
246
+ const txids = ['2df7b5059112a42fc40adb54ee36244cee0dd216c35ad6c4b6ef4631c14a0e83'] //, '9fb38fc87c6ff39f5c7321a4c689db535c024498ed20031434485c981dd7a182', '3fb6b02e1d001dded1daee3f59dcd684489b96a35a9dfb5082b4119a31689966', '72ea8d84a4c54dbca292f4a79a5ff08cb9917fc3127c1dcff0628aeba8b40823', '0564a515566bc43c1396becf12bbf2d82d821ae7b6e0ef404eedfa090d4877c2', '3b93e4327a50a7f4a421af9fbdec0206b3b7ba5252bc5a0142d0d64aa34c2e73', 'd4b0c3d820696afad43b43e095f3b8c3df52385bb4aeddff0212e0a472dd8e4e']
247
+ const userId = 111
248
+ const txs = await storage.findTransactions({ partial: { userId }, status: ['completed', 'unproven', 'failed'], orderDescending: true, paged: { limit: 50 } })
249
+ const allTxids = txs.map(tx => tx.txid!)
250
+ debugger;
251
+ const reqs = await storage.findProvenTxReqs({ partial: {}, txids: allTxids })
252
+ const beef = new Beef()
253
+ for (const req of reqs) {
254
+ beef.mergeRawTx(req.rawTx!)
255
+ }
256
+
257
+ for (const txid of txids) {
258
+ const o = await storage.findOutputs({ partial: { txid, userId } })
259
+ const tx = await storage.findTransactions({ partial: { txid, userId } })
260
+ if (o && tx) {
261
+ const ltx = await Format.toLogStringTableTransaction(tx[0], storage)
262
+ logger(ltx)
263
+ for (const btx of beef.txs) {
264
+ const tx = btx.tx!
265
+ for (const i of tx.inputs) {
266
+ if (i.sourceTXID === txid && i.sourceOutputIndex === 0) {
267
+ const sltx = Format.toLogStringBeefTxid(beef, btx.txid)
268
+ logger(sltx)
269
+ }
270
+ }
271
+ }
272
+ }
273
+ }
274
+ await storage.destroy()
275
+ })
276
+
177
277
  })
@@ -9,7 +9,7 @@ describe('KnexMigrations tests', () => {
9
9
  const env = _tu.getEnvFlags('test')
10
10
 
11
11
  beforeAll(async () => {
12
- const localSQLiteFile = await _tu.newTmpFile('migratetest.sqlite', false, false, true)
12
+ const localSQLiteFile = await _tu.newTmpFile('migratetest.sqlite', true, false, true)
13
13
  const knexSQLite = _tu.createLocalSQLite(localSQLiteFile)
14
14
  knexs.push(knexSQLite)
15
15