@bopen-io/wallet-toolbox 1.7.19 → 1.7.20-idb-fix.2

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.
@@ -229,25 +229,41 @@ async function createNewInputs(
229
229
  const o = i.output
230
230
  newInputs.push({ i, o })
231
231
  if (o) {
232
+ // IndexedDB transactions auto-commit when there are no pending IDB operations.
233
+ // Network calls (like getBeefForTransaction) create async gaps that cause the
234
+ // transaction to commit prematurely, making subsequent IDB operations fail.
235
+ // We do an initial read + potential network calls outside the transaction,
236
+ // then re-read inside the transaction to verify state hasn't changed.
237
+ const o2 = verifyOne(await storage.findOutputs({ partial: { outputId: o.outputId } }))
238
+ let competingBeef: number[] | undefined
239
+ if (o2.spentBy !== undefined) {
240
+ const spendingTx = await storage.findTransactionById(verifyId(o2.spentBy))
241
+ if (spendingTx && spendingTx.txid) {
242
+ // Fetch beef outside transaction (may involve network calls)
243
+ const beef = await storage.getBeefForTransaction(spendingTx.txid, {})
244
+ competingBeef = beef.toBinary()
245
+ }
246
+ }
247
+
248
+ // Transaction contains only IDB operations: re-read to verify state, then write
232
249
  await storage.transaction(async trx => {
233
- const o2 = verifyOne(await storage.findOutputs({ partial: { outputId: o.outputId }, trx }))
234
- if (o2.spentBy !== undefined) {
235
- const spendingTx = await storage.findTransactionById(verifyId(o2.spentBy), trx)
250
+ const o3 = verifyOne(await storage.findOutputs({ partial: { outputId: o.outputId }, trx }))
251
+ if (o3.spentBy !== undefined) {
252
+ const spendingTx = await storage.findTransactionById(verifyId(o3.spentBy), trx)
236
253
  if (spendingTx && spendingTx.txid) {
237
- const beef = await storage.getBeefForTransaction(spendingTx.txid, {})
238
254
  const rar: ReviewActionResult = {
239
255
  txid: '',
240
256
  status: 'doubleSpend',
241
257
  competingTxs: [spendingTx.txid!],
242
- competingBeef: beef.toBinary()
258
+ competingBeef: competingBeef
243
259
  }
244
260
  throw new WERR_REVIEW_ACTIONS([rar], [])
245
261
  }
246
262
  }
247
- if (o2.spendable != true) {
263
+ if (o3.spendable != true) {
248
264
  throw new WERR_INVALID_PARAMETER(
249
265
  `inputs[${i.vin}]`,
250
- `spendable output. output ${o.txid}:${o.vout} appears to have been spent (spendable=${o2.spendable}).`
266
+ `spendable output. output ${o.txid}:${o.vout} appears to have been spent (spendable=${o3.spendable}).`
251
267
  )
252
268
  }
253
269
  await storage.updateOutput(
@@ -1,14 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(cat:*)",
5
- "Bash(git -C /Users/satchmo/wallet-toolbox log --oneline -20 --all -- mobile/package.json)",
6
- "Bash(git -C /Users/satchmo/wallet-toolbox log --oneline -5 --all -- \"*.npmignore\")",
7
- "Bash(git -C /Users/satchmo/wallet-toolbox log --oneline)",
8
- "Bash(npm run build:*)",
9
- "Bash(git add:*)",
10
- "Bash(git commit:*)",
11
- "Bash(git push:*)"
12
- ]
13
- }
14
- }