@bsv/wallet-toolbox 1.3.2 → 1.3.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/wallet-toolbox",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "BRC100 conforming wallet, wallet storage and wallet signer components",
5
5
  "main": "./out/src/index.js",
6
6
  "types": "./out/src/index.d.ts",
@@ -338,12 +338,19 @@ export class OverlayUMPTokenInteractor implements UMPTokenInteractor {
338
338
  const inputs: CreateActionInput[] = []
339
339
  let inputToken: { beef: number[]; outputIndex: number } | undefined
340
340
  if (oldTokenToConsume?.currentOutpoint) {
341
- inputs.push({
342
- outpoint: oldTokenToConsume.currentOutpoint,
343
- unlockingScriptLength: 73, // typical signature length
344
- inputDescription: 'Consume old UMP token'
345
- })
346
341
  inputToken = await this.findByOutpoint(oldTokenToConsume.currentOutpoint)
342
+ // If there is no token on the overlay, we can't consume it. Just start over with a new token.
343
+ if (!inputToken) {
344
+ oldTokenToConsume = undefined
345
+
346
+ // Otherwise, add the input
347
+ } else {
348
+ inputs.push({
349
+ outpoint: oldTokenToConsume.currentOutpoint,
350
+ unlockingScriptLength: 73, // typical signature length
351
+ inputDescription: 'Consume old UMP token'
352
+ })
353
+ }
347
354
  }
348
355
 
349
356
  const outputs = [
@@ -2,6 +2,8 @@ import { ArcConfig, Beef, Transaction as BsvTransaction, ChainTracker, MerklePat
2
2
  import { ChaintracksServiceClient } from '../services/chaintracker'
3
3
  import { Chain, ReqHistoryNote } from './types'
4
4
  import { WalletError } from './WalletError'
5
+ import { TableOutput } from '../storage/schema/tables/Output'
6
+
5
7
  /**
6
8
  * Defines standard interfaces to access functionality implemented by external transaction processing services.
7
9
  */
@@ -110,6 +112,15 @@ export interface WalletServices {
110
112
  */
111
113
  getStatusForTxids(txids: string[], useNext?: boolean): Promise<GetStatusForTxidsResult>
112
114
 
115
+ /**
116
+ * Calls getUtxoStatus with the hash of the output's lockingScript,
117
+ * and ensures that the output's outpoint matches an unspent use of that script.
118
+ *
119
+ * @param output
120
+ * @returns true if the output appears to currently be spendable.
121
+ */
122
+ isUtxo(output: TableOutput): Promise<boolean>
123
+
113
124
  /**
114
125
  * Attempts to determine the UTXO status of a transaction output.
115
126
  *
@@ -1,5 +1,5 @@
1
1
  import { Transaction as BsvTransaction, Beef, ChainTracker, Utils } from '@bsv/sdk'
2
- import { asArray, asString, doubleSha256BE, sdk, sha256Hash, wait } from '../index.client'
2
+ import { asArray, asString, doubleSha256BE, sdk, sha256Hash, TableOutput, wait } from '../index.client'
3
3
  import { ServiceCollection } from './ServiceCollection'
4
4
  import { createDefaultWalletServicesOptions } from './createDefaultWalletServicesOptions'
5
5
  import { ChaintracksChainTracker } from './chaintracker'
@@ -143,6 +143,18 @@ export class Services implements sdk.WalletServices {
143
143
  return hash
144
144
  }
145
145
 
146
+ async isUtxo(output: TableOutput): Promise<boolean> {
147
+ if (!output.lockingScript) {
148
+ throw new sdk.WERR_INVALID_PARAMETER(
149
+ 'output.lockingScript',
150
+ 'validated by storage provider validateOutputScript.'
151
+ )
152
+ }
153
+ const hash = this.hashOutputScript(Utils.toHex(output.lockingScript))
154
+ const or = await this.getUtxoStatus(hash, undefined, `${output.txid}.${output.vout}`)
155
+ return or.isUtxo === true
156
+ }
157
+
146
158
  async getUtxoStatus(
147
159
  output: string,
148
160
  outputFormat?: sdk.GetUtxoStatusOutputFormat,
@@ -109,6 +109,8 @@ describe('ProvenTx class method tests', () => {
109
109
  results: []
110
110
  }),
111
111
 
112
+ isUtxo: async () => (true),
113
+
112
114
  getUtxoStatus: async () => ({
113
115
  name: 'mock-service',
114
116
  status: 'success',
@@ -28,7 +28,7 @@ describe('operations1 tests', () => {
28
28
 
29
29
  test('0 review and release all production invalid change utxos', async () => {
30
30
  const { env, storage } = await createMainReviewSetup()
31
- const users = await storage.findUsers({ partial: {} })
31
+ const users = await storage.findUsers({ partial: { userId: 296 } })
32
32
  const withInvalid: Record<number, { user: TableUser; outputs: WalletOutput[]; total: number }> = {}
33
33
  const vargs: ValidListOutputsArgs = {
34
34
  basket: specOpInvalidChange,
@@ -62,9 +62,9 @@ describe('operations1 tests', () => {
62
62
  await storage.destroy()
63
63
  })
64
64
 
65
- test('6 review and unfail false doubleSpends', async () => {
65
+ test('1 review and unfail false doubleSpends', async () => {
66
66
  const { env, storage, services } = await createMainReviewSetup()
67
- let offset = 2200
67
+ let offset = 2400
68
68
  const limit = 100
69
69
  let allUnfails: number[] = []
70
70
  for (;;) {
@@ -89,7 +89,7 @@ describe('operations1 tests', () => {
89
89
  await storage.destroy()
90
90
  })
91
91
 
92
- test('7 review and unfail false invalids', async () => {
92
+ test('2 review and unfail false invalids', async () => {
93
93
  const { env, storage, services } = await createMainReviewSetup()
94
94
  let offset = 500
95
95
  const limit = 100