keychat-save 1.4.0 → 1.4.1

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 (2) hide show
  1. package/index.mjs +27 -1
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -70,10 +70,36 @@ async function getUnspent (address) {
70
70
  height: u.height
71
71
  }))
72
72
  }
73
+ // ONE endpoint, TWO response contracts — normalise here so no caller has to know.
74
+ //
75
+ // The bridge answers in its own shape when our node can serve the tx:
76
+ // { outputs: [ { satoshis, script, index } ] }
77
+ // When it CANNOT — the node is pruned with no -txindex, so getrawtransaction fails for
78
+ // any confirmed tx in a discarded block — the web proxy falls back to WhatsOnChain and
79
+ // returns WoC's body untouched:
80
+ // { vout: [ { value, n, scriptPubKey: { hex } } ] }
81
+ //
82
+ // Callers looked only at `tx.outputs`, so on the WoC shape they iterated an empty array
83
+ // and reported "No OP_RETURN in tx." — a claim about the transaction, when the data was
84
+ // right there under a different field name. Measured 2026-08-26: 37 of 66 real saves
85
+ // unreadable. The share only grows, because a save falls to the WoC path once its block
86
+ // is pruned OR once a later save spends its change.
87
+ //
88
+ // Diagnosed 2026-08-24 (pt2) and hot-patched in the npx cache; the patch was never
89
+ // upstreamed, so publishing 1.4.0 replaced the cache with a clean copy and the bug came
90
+ // back. Fix it HERE, in the shared fetch, not at the call sites.
73
91
  async function getTx (txid) {
74
92
  const res = await fetch(`${BRIDGE}/api/tx/${txid}`)
75
93
  if (!res.ok) throw new Error(`tx ${res.status}`)
76
- return res.json()
94
+ const tx = await res.json()
95
+ if (!Array.isArray(tx.outputs) && Array.isArray(tx.vout)) {
96
+ tx.outputs = tx.vout.map(o => ({
97
+ satoshis: Math.round((o.value || 0) * 100_000_000),
98
+ script: o.scriptPubKey?.hex || '',
99
+ index: o.n
100
+ }))
101
+ }
102
+ return tx
77
103
  }
78
104
  async function getRawHex (txid) {
79
105
  const res = await fetch(`${BRIDGE}/api/tx/${txid}/hex`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keychat-save",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Save sessions, files and whole git repositories to the BSV blockchain via KeyChat",
5
5
  "type": "module",
6
6
  "bin": {