@bsv/wallet-toolbox 1.1.13 → 1.1.14

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 (132) hide show
  1. package/docs/README.md +8 -2
  2. package/docs/client.md +453 -346
  3. package/docs/open-rpc/index.html +46 -0
  4. package/docs/services.md +236 -211
  5. package/docs/setup.md +20 -4
  6. package/docs/storage.md +30 -5
  7. package/docs/wallet.md +453 -346
  8. package/out/src/Setup.d.ts.map +1 -1
  9. package/out/src/Setup.js.map +1 -1
  10. package/out/src/SetupClient.d.ts +9 -0
  11. package/out/src/SetupClient.d.ts.map +1 -1
  12. package/out/src/SetupClient.js +19 -3
  13. package/out/src/SetupClient.js.map +1 -1
  14. package/out/src/Wallet.d.ts +6 -0
  15. package/out/src/Wallet.d.ts.map +1 -1
  16. package/out/src/Wallet.js +57 -0
  17. package/out/src/Wallet.js.map +1 -1
  18. package/out/src/sdk/WalletServices.interfaces.d.ts +18 -13
  19. package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
  20. package/out/src/services/Services.d.ts +4 -11
  21. package/out/src/services/Services.d.ts.map +1 -1
  22. package/out/src/services/Services.js +19 -37
  23. package/out/src/services/Services.js.map +1 -1
  24. package/out/src/services/__tests/ARC.test.d.ts +2 -0
  25. package/out/src/services/__tests/ARC.test.d.ts.map +1 -0
  26. package/out/src/services/__tests/ARC.test.js +98 -0
  27. package/out/src/services/__tests/ARC.test.js.map +1 -0
  28. package/out/src/services/__tests/arcServices.test.d.ts +2 -0
  29. package/out/src/services/__tests/arcServices.test.d.ts.map +1 -0
  30. package/out/src/services/__tests/arcServices.test.js +7 -0
  31. package/out/src/services/__tests/arcServices.test.js.map +1 -0
  32. package/out/src/services/__tests/postBeef.test.js +45 -7
  33. package/out/src/services/__tests/postBeef.test.js.map +1 -1
  34. package/out/src/services/createDefaultWalletServicesOptions.d.ts +1 -0
  35. package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
  36. package/out/src/services/createDefaultWalletServicesOptions.js +16 -4
  37. package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
  38. package/out/src/services/providers/ARC.d.ts +91 -0
  39. package/out/src/services/providers/ARC.d.ts.map +1 -0
  40. package/out/src/services/providers/ARC.js +192 -0
  41. package/out/src/services/providers/ARC.js.map +1 -0
  42. package/out/src/services/providers/SdkWhatsOnChain.d.ts +21 -0
  43. package/out/src/services/providers/SdkWhatsOnChain.d.ts.map +1 -0
  44. package/out/src/services/providers/SdkWhatsOnChain.js +67 -0
  45. package/out/src/services/providers/SdkWhatsOnChain.js.map +1 -0
  46. package/out/src/services/providers/WhatsOnChain.d.ts +35 -0
  47. package/out/src/services/providers/WhatsOnChain.d.ts.map +1 -0
  48. package/out/src/services/providers/WhatsOnChain.js +266 -0
  49. package/out/src/services/providers/WhatsOnChain.js.map +1 -0
  50. package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts +2 -0
  51. package/out/src/services/providers/__tests/WhatsOnChain.test.d.ts.map +1 -0
  52. package/out/src/services/providers/__tests/WhatsOnChain.test.js +176 -0
  53. package/out/src/services/providers/__tests/WhatsOnChain.test.js.map +1 -0
  54. package/out/src/storage/methods/createAction.d.ts.map +1 -1
  55. package/out/src/storage/methods/createAction.js +9 -2
  56. package/out/src/storage/methods/createAction.js.map +1 -1
  57. package/out/src/storage/methods/generateChange.d.ts +12 -1
  58. package/out/src/storage/methods/generateChange.d.ts.map +1 -1
  59. package/out/src/storage/methods/generateChange.js +24 -1
  60. package/out/src/storage/methods/generateChange.js.map +1 -1
  61. package/out/src/storage/methods/processAction.d.ts.map +1 -1
  62. package/out/src/storage/methods/processAction.js +1 -1
  63. package/out/src/storage/methods/processAction.js.map +1 -1
  64. package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js +0 -1
  65. package/out/src/storage/schema/entities/__tests/ProvenTxTests.test.js.map +1 -1
  66. package/out/src/storage/sync/StorageMySQLDojoReader.js +1 -1
  67. package/out/src/storage/sync/StorageMySQLDojoReader.js.map +1 -1
  68. package/out/src/utility/utilityHelpers.js +1 -1
  69. package/out/src/utility/utilityHelpers.js.map +1 -1
  70. package/out/test/Wallet/StorageClient/storageClient.man.test.js +22 -3
  71. package/out/test/Wallet/StorageClient/storageClient.man.test.js.map +1 -1
  72. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js +40 -0
  73. package/out/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.js.map +1 -1
  74. package/out/test/services/Services.test.js +0 -31
  75. package/out/test/services/Services.test.js.map +1 -1
  76. package/out/test/utils/TestUtilsWalletStorage.d.ts +26 -18
  77. package/out/test/utils/TestUtilsWalletStorage.d.ts.map +1 -1
  78. package/out/test/utils/TestUtilsWalletStorage.js +135 -27
  79. package/out/test/utils/TestUtilsWalletStorage.js.map +1 -1
  80. package/out/test/wallet/list/listActions2.test.js +36 -2
  81. package/out/test/wallet/list/listActions2.test.js.map +1 -1
  82. package/out/tsconfig.all.tsbuildinfo +1 -1
  83. package/package.json +5 -7
  84. package/src/Setup.ts +0 -1
  85. package/src/SetupClient.ts +26 -6
  86. package/src/Wallet.ts +66 -2
  87. package/src/sdk/WalletServices.interfaces.ts +19 -14
  88. package/src/services/Services.ts +23 -62
  89. package/src/services/__tests/ARC.test.ts +110 -0
  90. package/src/services/__tests/arcServices.test.ts +8 -0
  91. package/src/services/__tests/postBeef.test.ts +47 -9
  92. package/src/services/createDefaultWalletServicesOptions.ts +19 -6
  93. package/src/services/providers/ARC.ts +289 -0
  94. package/src/services/providers/SdkWhatsOnChain.ts +96 -0
  95. package/src/services/providers/WhatsOnChain.ts +369 -0
  96. package/src/services/providers/__tests/WhatsOnChain.test.ts +227 -0
  97. package/src/storage/methods/createAction.ts +26 -4
  98. package/src/storage/methods/generateChange.ts +42 -2
  99. package/src/storage/methods/processAction.ts +2 -1
  100. package/src/storage/schema/entities/__tests/ProvenTxTests.test.ts +0 -1
  101. package/src/storage/sync/StorageMySQLDojoReader.ts +1 -1
  102. package/src/utility/utilityHelpers.ts +1 -1
  103. package/test/Wallet/StorageClient/storageClient.man.test.ts +30 -4
  104. package/test/Wallet/sync/Wallet.updateWalletLegacyTestData.man.test.ts +54 -0
  105. package/test/services/Services.test.ts +0 -30
  106. package/test/utils/TestUtilsWalletStorage.ts +175 -45
  107. package/test/wallet/list/listActions2.test.ts +4 -7
  108. package/out/src/services/__tests/postBeefToArcTaal.test.d.ts +0 -2
  109. package/out/src/services/__tests/postBeefToArcTaal.test.d.ts.map +0 -1
  110. package/out/src/services/__tests/postBeefToArcTaal.test.js +0 -479
  111. package/out/src/services/__tests/postBeefToArcTaal.test.js.map +0 -1
  112. package/out/src/services/__tests/postTxs.test.d.ts +0 -2
  113. package/out/src/services/__tests/postTxs.test.d.ts.map +0 -1
  114. package/out/src/services/__tests/postTxs.test.js +0 -28
  115. package/out/src/services/__tests/postTxs.test.js.map +0 -1
  116. package/out/src/services/providers/arcServices.d.ts +0 -62
  117. package/out/src/services/providers/arcServices.d.ts.map +0 -1
  118. package/out/src/services/providers/arcServices.js +0 -375
  119. package/out/src/services/providers/arcServices.js.map +0 -1
  120. package/out/src/services/providers/whatsonchain.d.ts +0 -17
  121. package/out/src/services/providers/whatsonchain.d.ts.map +0 -1
  122. package/out/src/services/providers/whatsonchain.js +0 -130
  123. package/out/src/services/providers/whatsonchain.js.map +0 -1
  124. package/out/test/examples/README.man.test.d.ts +0 -2
  125. package/out/test/examples/README.man.test.d.ts.map +0 -1
  126. package/out/test/examples/README.man.test.js +0 -47
  127. package/out/test/examples/README.man.test.js.map +0 -1
  128. package/src/services/__tests/postBeefToArcTaal.test.ts +0 -487
  129. package/src/services/__tests/postTxs.test.ts +0 -28
  130. package/src/services/providers/arcServices.ts +0 -578
  131. package/src/services/providers/whatsonchain.ts +0 -170
  132. package/test/examples/README.man.test.ts +0 -53
@@ -1,11 +1,20 @@
1
1
  import { sdk, validateStorageFeeModel } from '../../index.client'
2
2
 
3
+ /**
4
+ * An output of this satoshis amount will be adjusted to the largest fundable amount.
5
+ */
6
+ export const maxPossibleSatoshis = 2099999999999999
7
+
3
8
  export interface GenerateChangeSdkResult {
4
9
  allocatedChangeInputs: GenerateChangeSdkChangeInput[]
5
10
  changeOutputs: GenerateChangeSdkChangeOutput[]
6
11
  size: number
7
12
  fee: number
8
13
  satsPerKb: number
14
+ maxPossibleSatoshisAdjustment?: {
15
+ fixedOutputIndex: number
16
+ satoshis: number
17
+ }
9
18
  }
10
19
 
11
20
  /**
@@ -38,7 +47,7 @@ export async function generateChangeSdk(
38
47
 
39
48
  // eslint-disable-next-line no-useless-catch
40
49
  try {
41
- validateGenerateChangeSdkParams(params)
50
+ const vgcpr = validateGenerateChangeSdkParams(params)
42
51
 
43
52
  const satsPerKb = params.feeModel.value || 0
44
53
 
@@ -269,6 +278,20 @@ export async function generateChangeSdk(
269
278
  */
270
279
  await fundTransaction()
271
280
 
281
+ if (feeExcess() < 0 && vgcpr.hasMaxPossibleOutput !== undefined) {
282
+ // Reduce the fixed output with satoshis of maxPossibleSatoshis to what will just fund the transaction...
283
+ if (
284
+ fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis !==
285
+ maxPossibleSatoshis
286
+ )
287
+ throw new sdk.WERR_INTERNAL()
288
+ fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis += feeExcess()
289
+ r.maxPossibleSatoshisAdjustment = {
290
+ fixedOutputIndex: vgcpr.hasMaxPossibleOutput,
291
+ satoshis: fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis
292
+ }
293
+ }
294
+
272
295
  /**
273
296
  * Trigger an account funding event if we don't have enough to cover this transaction.
274
297
  */
@@ -448,11 +471,18 @@ export interface GenerateChangeSdkChangeOutput {
448
471
  lockingScriptLength: number
449
472
  }
450
473
 
474
+ export interface ValidateGenerateChangeSdkParamsResult {
475
+ hasMaxPossibleOutput?: number
476
+ }
477
+
451
478
  export function validateGenerateChangeSdkParams(
452
479
  params: GenerateChangeSdkParams
453
- ) {
480
+ ): ValidateGenerateChangeSdkParamsResult {
454
481
  if (!Array.isArray(params.fixedInputs))
455
482
  throw new sdk.WERR_INVALID_PARAMETER('fixedInputs', 'an array of objects')
483
+
484
+ const r: ValidateGenerateChangeSdkParamsResult = {}
485
+
456
486
  params.fixedInputs.forEach((x, i) => {
457
487
  sdk.validateSatoshis(x.satoshis, `fixedInputs[${i}].satoshis`)
458
488
  sdk.validateInteger(
@@ -473,6 +503,14 @@ export function validateGenerateChangeSdkParams(
473
503
  undefined,
474
504
  0
475
505
  )
506
+ if (x.satoshis === maxPossibleSatoshis) {
507
+ if (r.hasMaxPossibleOutput !== undefined)
508
+ throw new sdk.WERR_INVALID_PARAMETER(
509
+ `fixedOutputs[${i}].satoshis`,
510
+ `valid satoshis amount. Only one 'maxPossibleSatoshis' output allowed.`
511
+ )
512
+ r.hasMaxPossibleOutput = i
513
+ }
476
514
  })
477
515
 
478
516
  params.feeModel = validateStorageFeeModel(params.feeModel)
@@ -492,6 +530,8 @@ export function validateGenerateChangeSdkParams(
492
530
  params.changeUnlockingScriptLength,
493
531
  `changeUnlockingScriptLength`
494
532
  )
533
+
534
+ return r
495
535
  }
496
536
 
497
537
  export interface GenerateChangeSdkStorageChange
@@ -24,6 +24,7 @@ import {
24
24
  TxScriptOffsets,
25
25
  validateStorageFeeModel,
26
26
  verifyId,
27
+ verifyInteger,
27
28
  verifyNumber,
28
29
  verifyOne,
29
30
  verifyOneOrNone,
@@ -359,7 +360,7 @@ async function validateCommitNewTxToStorageArgs(
359
360
  // outputs spendable will be updated for change to true and all others to !!o.tracked when tx has been broadcast
360
361
  // MAX_OUTPUTSCRIPT_LENGTH is limit for scripts left in outputs table
361
362
  for (const o of vargs.outputOutputs) {
362
- const vout = verifyTruthy(o.vout)
363
+ const vout = verifyInteger(o.vout)
363
364
  const offset = vargs.txScriptOffsets.outputs[vout]
364
365
  const rawTxScript = asString(
365
366
  vargs.rawTx.slice(offset.offset, offset.offset + offset.length)
@@ -100,7 +100,6 @@ describe('ProvenTx class method tests', () => {
100
100
  getHeight: async () => height,
101
101
  getBsvExchangeRate: async () => 0,
102
102
  getFiatExchangeRate: async () => 1,
103
- postTxs: async () => [],
104
103
  postBeef: async () => [],
105
104
  getUtxoStatus: async () => ({
106
105
  name: 'mock-service',
@@ -298,7 +298,7 @@ export class StorageMySQLDojoReader extends StorageReader {
298
298
  spendable: !!d.spendable,
299
299
  change: d.providedBy !== 'you' && d.purpose === 'change',
300
300
  outputDescription: (d.description || '').trim(),
301
- vout: verifyInteger(d.vout),
301
+ vout: verifyInteger(typeof d.vout !== 'number' ? 9999 : d.vout),
302
302
  satoshis: verifyInteger(d.amount),
303
303
  providedBy: verifyTruthy(d.providedBy || '')
304
304
  .trim()
@@ -87,7 +87,7 @@ export function verifyTruthy<T>(
87
87
  v: T | null | undefined,
88
88
  description?: string
89
89
  ): T {
90
- if (v == null)
90
+ if (!v)
91
91
  throw new sdk.WERR_INTERNAL(description ?? 'A truthy value is required.')
92
92
  return v
93
93
  }
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
- import { StorageClient } from '../../../src/index.all'
2
+ import { sdk, StorageClient } from '../../../src/index.all'
3
3
  import { _tu, TestWalletOnly } from '../../utils/TestUtilsWalletStorage'
4
4
 
5
5
  /**
@@ -32,17 +32,17 @@ describe('walletStorageClient test', () => {
32
32
  {
33
33
  const client = new StorageClient(
34
34
  wallet,
35
- 'https://staging-dojo.babbage.systems'
35
+ 'https://staging-storage.babbage.systems'
36
36
  )
37
37
  await storage.addWalletStorageProvider(client)
38
38
  await storage.updateBackups()
39
39
  }
40
40
  })
41
41
 
42
- test('2 create storage client wallet', async () => {
42
+ test('2 create storage client backup for test wallet', async () => {
43
43
  const ctx = await _tu.createTestWalletWithStorageClient({
44
44
  rootKeyHex: '1'.repeat(64),
45
- endpointUrl: 'https://staging-dojo.babbage.systems'
45
+ endpointUrl: 'https://staging-storage.babbage.systems'
46
46
  })
47
47
  ctxs.push(ctx)
48
48
  const { wallet, storage } = ctx
@@ -52,4 +52,30 @@ describe('walletStorageClient test', () => {
52
52
  expect(auth.userId).toBeTruthy()
53
53
  }
54
54
  })
55
+
56
+ test('3 create storage client backup for main wallet', async () => {
57
+ const filePath = process.env.MY_MAIN_FILEPATH
58
+ const identityKey = process.env.MY_MAIN_IDENTITY || ''
59
+ const rootKeyHex = env.devKeys[identityKey]
60
+ expect(filePath && identityKey && rootKeyHex)
61
+
62
+ const chain: sdk.Chain = 'main'
63
+
64
+ const main = await _tu.createSQLiteTestWallet({
65
+ filePath,
66
+ databaseName: 'tone42',
67
+ chain,
68
+ rootKeyHex
69
+ })
70
+ ctxs.push(main)
71
+
72
+ {
73
+ const client = new StorageClient(
74
+ main.wallet,
75
+ 'https://storage.babbage.systems'
76
+ )
77
+ await main.storage.addWalletStorageProvider(client)
78
+ await main.storage.updateBackups()
79
+ }
80
+ })
55
81
  })
@@ -66,6 +66,60 @@ describe('Wallet sync tests', () => {
66
66
  done0 = true
67
67
  })
68
68
 
69
+ test.skip('0a sync production dojo to local MySQL', async () => {
70
+ console.log(
71
+ 'Importing from production dojo to local MySQL productiondojotone'
72
+ )
73
+ const identityKeyTone = process.env.MY_MAIN_IDENTITY || ''
74
+ const rootKeyHex = env.devKeys[identityKeyTone]
75
+ const chain: sdk.Chain = 'main'
76
+ const connection = JSON.parse(process.env.MAIN_DOJO_CONNECTION || '')
77
+ const readerKnex = _tu.createMySQLFromConnection(connection)
78
+ const reader = new StorageMySQLDojoReader({ chain, knex: readerKnex })
79
+ const writer = await _tu.createMySQLTestWallet({
80
+ databaseName: 'productiondojotone',
81
+ chain: 'main',
82
+ rootKeyHex,
83
+ dropAll: true
84
+ })
85
+
86
+ const identityKey = writer.identityKey
87
+ await writer.storage.syncFromReader(
88
+ identityKey,
89
+ new StorageSyncReader({ identityKey }, reader)
90
+ )
91
+
92
+ await reader.destroy()
93
+ await writer.activeStorage.destroy()
94
+ })
95
+
96
+ test('0b sweep mysql dojo sync to new sqlite', async () => {
97
+ const identityKeyTone = process.env.MY_MAIN_IDENTITY || ''
98
+ const rootKeyHex = env.devKeys[identityKeyTone]
99
+ const chain: sdk.Chain = 'main'
100
+
101
+ const sweepFrom = await _tu.createMySQLTestWallet({
102
+ databaseName: 'productiondojotone',
103
+ chain: 'main',
104
+ rootKeyHex
105
+ })
106
+
107
+ const sweepTo = await _tu.createSQLiteTestWallet({
108
+ filePath: '/Users/tone/Kz/tone42.sqlite',
109
+ databaseName: 'tone42',
110
+ chain: 'main',
111
+ rootKeyHex
112
+ })
113
+
114
+ //await sweepTo.activeStorage.updateProvenTxReq(2, { status: 'invalid' })
115
+ //await sweepTo.activeStorage.updateTransactionStatus('failed', 2)
116
+
117
+ await sweepFrom.wallet.sweepTo(sweepTo.wallet)
118
+
119
+ await sweepTo.wallet.destroy()
120
+ await sweepFrom.wallet.destroy()
121
+ })
122
+
69
123
  test('1 aggressively purge records from MySQL stagingdojotone', async () => {
70
124
  await waitFor0()
71
125
 
@@ -120,34 +120,4 @@ describe('Wallet services tests', () => {
120
120
  }
121
121
  }
122
122
  })
123
-
124
- test('6 postBeef', async () => {
125
- for (const { chain, wallet, services } of ctxs) {
126
- if (!wallet.services || !services)
127
- throw new sdk.WERR_INTERNAL('test requires setup with services')
128
- {
129
- if (chain === 'main') {
130
- const txid =
131
- 'b56ccf7dd0eb6bb0341cb92a2045d902106e4c2add0a4af057c85e9dfaaebddf'
132
- const rawTx = await wallet.services.getRawTx(txid)
133
- const mp = await wallet.services.getMerklePath(txid)
134
- const beef = new Beef()
135
- beef.mergeBump(mp.merklePath!)
136
- beef.mergeRawTx(rawTx.rawTx!)
137
- // Using postTxs as postBeef is problematic still...
138
- const r = await wallet.services.postTxs(beef, [txid])
139
- if (r[0].status === 'error') {
140
- console.log(`
141
- ${r[0].error?.message}
142
- ${beef.toLogString()}
143
- ${beef.toHex()}
144
- `)
145
- } else {
146
- expect(r[0].txidResults[0].txid).toBe(txid)
147
- expect(r[0].status).toBe('success')
148
- }
149
- }
150
- }
151
- }
152
- })
153
123
  })
@@ -11,6 +11,7 @@ import {
11
11
  SatoshiValue,
12
12
  SignActionArgs,
13
13
  SignActionResult,
14
+ Transaction,
14
15
  Utils,
15
16
  WalletAction,
16
17
  WalletActionInput,
@@ -49,7 +50,9 @@ import {
49
50
  TableCertificate,
50
51
  TableCertificateField,
51
52
  TableOutputTagMap,
52
- TableOutputTag
53
+ TableOutputTag,
54
+ ScriptTemplateBRC29,
55
+ Setup
53
56
  } from '../../src/index.all'
54
57
 
55
58
  import { Knex, knex as makeKnex } from 'knex'
@@ -57,22 +60,22 @@ import { Knex, knex as makeKnex } from 'knex'
57
60
  import * as dotenv from 'dotenv'
58
61
  dotenv.config()
59
62
 
60
- const localMySqlConnection = process.env.LOCAL_MYSQL_CONNECTION || ''
63
+ const localMySqlConnection = process.env.MYSQL_CONNECTION || ''
61
64
 
62
65
  export interface TuEnv {
63
66
  chain: sdk.Chain
64
- userId: number
65
67
  identityKey: string
66
- mainTaalApiKey: string
67
- testTaalApiKey: string
68
+ identityKey2: string
69
+ taalApiKey: string
68
70
  devKeys: Record<string, string>
69
- noMySQL: boolean
71
+ runMySQL: boolean
70
72
  runSlowTests: boolean
71
73
  logTests: boolean
72
74
  }
73
75
 
74
76
  export abstract class TestUtilsWalletStorage {
75
- static getEnv(chain: sdk.Chain) {
77
+
78
+ static getEnv(chain: sdk.Chain): TuEnv {
76
79
  // Identity keys of the lead maintainer of this repo...
77
80
  const identityKey =
78
81
  (chain === 'main'
@@ -86,18 +89,13 @@ export abstract class TestUtilsWalletStorage {
86
89
  const logTests = !!process.env.LOGTESTS
87
90
  const runMySQL = !!process.env.RUNMYSQL
88
91
  const runSlowTests = !!process.env.RUNSLOWTESTS
92
+ const mainTaalApiKey = process.env.MAIN_TAAL_API_KEY || ''
93
+ const testTaalApiKey = process.env.TEST_TAAL_API_KEY || ''
89
94
  return {
90
95
  chain,
91
96
  identityKey,
92
97
  identityKey2,
93
- mainTaalApiKey: verifyTruthy(
94
- process.env.MAIN_TAAL_API_KEY || '',
95
- `.env value for 'mainTaalApiKey' is required.`
96
- ),
97
- testTaalApiKey: verifyTruthy(
98
- process.env.TEST_TAAL_API_KEY || '',
99
- `.env value for 'testTaalApiKey' is required.`
100
- ),
98
+ taalApiKey: chain === 'main' ? mainTaalApiKey : testTaalApiKey,
101
99
  devKeys: JSON.parse(DEV_KEYS) as Record<string, string>,
102
100
  runMySQL,
103
101
  runSlowTests,
@@ -281,17 +279,16 @@ export abstract class TestUtilsWalletStorage {
281
279
  endpointUrl?: string
282
280
  chain?: sdk.Chain
283
281
  }): Promise<TestWalletOnly> {
284
- if (args.chain === 'main')
285
- throw new sdk.WERR_INVALID_PARAMETER(
286
- 'chain',
287
- `'test' for now, 'main' is not yet supported.`
288
- )
289
-
282
+ args.chain ||= 'test'
290
283
  const wo = await _tu.createWalletOnly({
291
- chain: 'test',
284
+ chain: args.chain,
292
285
  rootKeyHex: args.rootKeyHex
293
286
  })
294
- args.endpointUrl ||= 'https://staging-dojo.babbage.systems'
287
+ args.endpointUrl ||=
288
+ args.chain === 'main'
289
+ ? 'https://storage.babbage.systems'
290
+ : 'https://staging-storage.babbage.systems'
291
+
295
292
  const client = new StorageClient(wo.wallet, args.endpointUrl)
296
293
  await wo.storage.addWalletStorageProvider(client)
297
294
  await wo.storage.makeAvailable()
@@ -1224,7 +1221,7 @@ export abstract class TestUtilsWalletStorage {
1224
1221
 
1225
1222
  // Need to convert
1226
1223
  const lockingScriptValue = input.sourceLockingScript
1227
- ? hexStringToNumberArray(input.sourceLockingScript)
1224
+ ? Utils.toArray(input.sourceLockingScript, 'hex')
1228
1225
  : undefined
1229
1226
 
1230
1227
  prevOutput = await _tu.insertTestOutput(
@@ -1396,6 +1393,160 @@ export abstract class TestUtilsWalletStorage {
1396
1393
  )
1397
1394
  }
1398
1395
  }
1396
+
1397
+ static async createWalletSetupEnv(chain: sdk.Chain): Promise<TestWalletOnly> {
1398
+ const env = Setup.getEnv(chain)
1399
+ const rootKeyHex = env.devKeys[env.identityKey]
1400
+
1401
+ if (env.filePath) {
1402
+ return await _tu.createSQLiteTestWallet({
1403
+ filePath: env.filePath,
1404
+ databaseName: 'setupEnvWallet',
1405
+ chain,
1406
+ rootKeyHex
1407
+ })
1408
+ }
1409
+
1410
+ return await _tu.createTestWalletWithStorageClient({
1411
+ chain,
1412
+ rootKeyHex
1413
+ })
1414
+ }
1415
+
1416
+ /**
1417
+ * Create a pair of transacitons that cancel out, other than the transaciton fees.
1418
+ * Both created transactions are left with status 'noSend'.
1419
+ * This allows the transactions to either be broadcast by an external party,
1420
+ * or they may be aborted.
1421
+ *
1422
+ * `doubleSpendTx` should only be used for double spend testing.
1423
+ * It attempts to forward the txidDo input, which should already have been reclaimed by txidUndo, to a random private key output.
1424
+ *
1425
+ * @param wallet the wallet that will create both transactions, or Chain and createWalletEnv is used to create a wallet.
1426
+ * @param satoshis amount of new output created and consumed. Defaults to 41.
1427
+ * @returns { txidDo: string, txidUndo: string, beef: Beef, doubleSpendTx: transaction }
1428
+ */
1429
+ static async createNoSendTxPair(
1430
+ wallet: Wallet | sdk.Chain,
1431
+ satoshis = 41
1432
+ ): Promise<{
1433
+ txidDo: string
1434
+ txidUndo: string
1435
+ beef: Beef
1436
+ doubleSpendTx: Transaction
1437
+ }> {
1438
+ let destroyWallet = false
1439
+ if (wallet === 'main' || wallet === 'test') {
1440
+ wallet = (await _tu.createWalletSetupEnv(wallet)).wallet
1441
+ destroyWallet = true
1442
+ }
1443
+
1444
+ const derivationPrefix = randomBytesBase64(8)
1445
+ const derivationSuffix = randomBytesBase64(8)
1446
+ const keyDeriver = wallet.keyDeriver
1447
+
1448
+ const t = new ScriptTemplateBRC29({
1449
+ derivationPrefix,
1450
+ derivationSuffix,
1451
+ keyDeriver
1452
+ })
1453
+
1454
+ let label = 'doTxPair'
1455
+ const car = await wallet.createAction({
1456
+ outputs: [
1457
+ {
1458
+ lockingScript: t
1459
+ .lock(keyDeriver.rootKey.toString(), wallet.identityKey)
1460
+ .toHex(),
1461
+ satoshis,
1462
+ outputDescription: label,
1463
+ customInstructions: JSON.stringify({
1464
+ derivationPrefix,
1465
+ derivationSuffix,
1466
+ type: 'BRC29'
1467
+ })
1468
+ }
1469
+ ],
1470
+ options: {
1471
+ randomizeOutputs: false,
1472
+ noSend: true
1473
+ },
1474
+ description: label
1475
+ })
1476
+
1477
+ const beef = Beef.fromBinary(car.tx!)
1478
+ const txidDo = car.txid!
1479
+ const outpoint = `${car.txid!}.0`
1480
+
1481
+ const unlock = t.unlock(
1482
+ keyDeriver.rootKey.toString(),
1483
+ wallet.identityKey,
1484
+ satoshis
1485
+ )
1486
+
1487
+ label = 'undoTxPair'
1488
+
1489
+ const car2 = await wallet.createAction({
1490
+ inputBEEF: beef.toBinary(),
1491
+ inputs: [
1492
+ {
1493
+ outpoint,
1494
+ unlockingScriptLength: t.unlockLength,
1495
+ inputDescription: label
1496
+ }
1497
+ ],
1498
+ description: label,
1499
+ options: {
1500
+ noSend: true,
1501
+ noSendChange: car.noSendChange
1502
+ }
1503
+ })
1504
+
1505
+ const st = car2.signableTransaction!
1506
+ const stBeef = Beef.fromBinary(st.tx)
1507
+ const tx = wallet.beef.findAtomicTransaction(stBeef.txs.slice(-1)[0].txid)!
1508
+ tx.inputs[0].unlockingScriptTemplate = unlock
1509
+ await tx.sign()
1510
+ const unlockingScript = tx.inputs[0].unlockingScript!.toHex()
1511
+
1512
+ const signArgs: SignActionArgs = {
1513
+ reference: st.reference,
1514
+ spends: { 0: { unlockingScript } },
1515
+ options: {
1516
+ noSend: true
1517
+ }
1518
+ }
1519
+
1520
+ const sar = await wallet.signAction(signArgs)
1521
+
1522
+ beef.mergeBeef(sar.tx!)
1523
+ const txidUndo = sar.txid!
1524
+
1525
+ if (destroyWallet) await wallet.destroy()
1526
+
1527
+ const doubleSpendTx = new Transaction()
1528
+ const sourceTXID = txidDo
1529
+ const sourceOutputIndex = 0
1530
+ const sourceSatoshis = satoshis
1531
+ doubleSpendTx.addInput({
1532
+ sourceOutputIndex,
1533
+ sourceTXID,
1534
+ sourceTransaction: beef.findAtomicTransaction(sourceTXID),
1535
+ unlockingScriptTemplate: unlock
1536
+ })
1537
+ doubleSpendTx.addOutput({
1538
+ satoshis: sourceSatoshis - 10,
1539
+ lockingScript: new P2PKH().lock(PrivateKey.fromRandom().toAddress())
1540
+ })
1541
+ await doubleSpendTx.sign()
1542
+
1543
+ return {
1544
+ txidDo,
1545
+ txidUndo,
1546
+ beef,
1547
+ doubleSpendTx
1548
+ }
1549
+ }
1399
1550
  }
1400
1551
 
1401
1552
  export abstract class _tu extends TestUtilsWalletStorage {}
@@ -1535,18 +1686,6 @@ function mockPostServices(
1535
1686
  return Promise.resolve([r])
1536
1687
  }
1537
1688
  )
1538
- services.postTxs = jest
1539
- .fn()
1540
- .mockImplementation(
1541
- (beef: Beef, txids: string[]): Promise<sdk.PostBeefResult[]> => {
1542
- const r: sdk.PostBeefResult = {
1543
- name: 'mock',
1544
- status: 'success',
1545
- txidResults: txids.map(txid => ({ txid, status }))
1546
- }
1547
- return Promise.resolve([r])
1548
- }
1549
- )
1550
1689
  }
1551
1690
  }
1552
1691
 
@@ -2179,12 +2318,3 @@ export async function logInput(
2179
2318
  export function logBasket(basket: TableOutputBasket): string {
2180
2319
  return `\n-- Basket --\nName: ${basket.name}\n`
2181
2320
  }
2182
-
2183
- export function hexStringToNumberArray(hexString: string): number[] {
2184
- const sanitizedHex = hexString.replace(/[^a-fA-F0-9]/g, '')
2185
- const result: number[] = []
2186
- for (let i = 0; i < sanitizedHex.length; i += 2) {
2187
- result.push(parseInt(sanitizedHex.substr(i, 2), 16))
2188
- }
2189
- return result
2190
- }
@@ -1,12 +1,9 @@
1
- //@ts-nocheck
2
1
  import * as bsv from '@bsv/sdk'
3
2
  import { sdk, StorageProvider } from '../../../src/index.client'
4
3
  import {
5
4
  _tu,
6
5
  expectToThrowWERR,
7
- hexStringToNumberArray,
8
6
  MockData,
9
- TestSetup2,
10
7
  TestWalletNoSetup
11
8
  } from '../../utils/TestUtilsWalletStorage'
12
9
 
@@ -57,7 +54,7 @@ describe('listActions2 single action tests', () => {
57
54
  beforeEach(async () => {
58
55
  ctxs = []
59
56
  const args = {
60
- chain: 'test',
57
+ chain: <sdk.Chain>'test',
61
58
  mockData,
62
59
  databaseName: testName(),
63
60
  rootKeyHex: '2'.repeat(64),
@@ -743,7 +740,7 @@ describe('listActions2 single action tests', () => {
743
740
  vout: 2,
744
741
  outputDescription: 'new description',
745
742
  basketId: 1,
746
- lockingScript: hexStringToNumberArray('0123456789abcdef')
743
+ lockingScript: bsv.Utils.toArray('0123456789abcdef', 'hex')
747
744
  })
748
745
  await storage.updateOutputTag(2, { tag: 'new tag' })
749
746
  await storage.updateOutputTagMap(1, 2, {})
@@ -773,7 +770,7 @@ describe('listActions2 single action tests', () => {
773
770
  vout: 2,
774
771
  outputDescription: 'new description',
775
772
  basketId: 1,
776
- lockingScript: hexStringToNumberArray('0123456789abcdef')
773
+ lockingScript: bsv.Utils.toArray('0123456789abcdef', 'hex')
777
774
  })
778
775
  await storage.updateOutputTag(2, { tag: 'new tag' })
779
776
  await storage.updateOutputTagMap(1, 2, {})
@@ -1243,7 +1240,7 @@ describe('listActions2 two action tests', () => {
1243
1240
  beforeEach(async () => {
1244
1241
  ctxs = []
1245
1242
  const args = {
1246
- chain: 'test',
1243
+ chain: <sdk.Chain>'test',
1247
1244
  mockData,
1248
1245
  databaseName: testName(),
1249
1246
  rootKeyHex: '2'.repeat(64),
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=postBeefToArcTaal.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"postBeefToArcTaal.test.d.ts","sourceRoot":"","sources":["../../../../src/services/__tests/postBeefToArcTaal.test.ts"],"names":[],"mappings":""}