keychat-save 1.0.0 → 1.1.0

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 +37 -4
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -193,6 +193,32 @@ async function cmdSave (label, body) {
193
193
  console.log(` Tx: ${txid}`)
194
194
  }
195
195
 
196
+ async function cmdLoadByTxid (txid) {
197
+ if (!existsSync(WIF_PATH)) { console.error('Run: keychat-save init'); process.exit(1) }
198
+ const key = PrivateKey.fromWif(readFileSync(WIF_PATH, 'utf8').trim())
199
+ const tx = await getTx(txid)
200
+ let opReturnHex = null
201
+ for (const o of (tx.outputs || [])) {
202
+ const s = o.script || ''
203
+ if (s.startsWith('006a') || s.startsWith('6a') || o.satoshis === 0) { opReturnHex = s; break }
204
+ }
205
+ if (!opReturnHex) { console.error('No OP_RETURN in tx.'); process.exit(1) }
206
+ const parts = extractParts(opReturnHex)
207
+ if (!parts || parts.length < 5 || parts[0] !== SAVE_PREFIX || parts[1] !== VERSION) {
208
+ console.error('Not a KSAV save tx.'); process.exit(1)
209
+ }
210
+ const cipherHex = parts[3]
211
+ const tsHex = parts[4]
212
+ const decrypted = decrypt(Array.from(hexToBytes(cipherHex)), key)
213
+ let label = 'Untitled', body = decrypted
214
+ try {
215
+ const env = JSON.parse(decrypted)
216
+ if (env.kind === 'save') { label = env.label || 'Untitled'; body = env.body || '' }
217
+ } catch {}
218
+ console.log(`[${label}] — ${new Date(parseInt(tsHex, 16) * 1000).toLocaleString()}`)
219
+ console.log(body)
220
+ }
221
+
196
222
  async function cmdLoad (opts = {}) {
197
223
  if (!existsSync(WIF_PATH)) { console.error('Run: keychat-save init'); process.exit(1) }
198
224
  const key = PrivateKey.fromWif(readFileSync(WIF_PATH, 'utf8').trim())
@@ -269,10 +295,16 @@ if (cmd === 'init') {
269
295
  if (!body) { console.error('Usage: keychat-save save "label" "content"'); process.exit(1) }
270
296
  await cmdSave(label, body)
271
297
  } else if (cmd === 'load') {
272
- const opts = {}
273
- if (args.includes('--last')) opts.last = true
274
- if (args.includes('--search')) opts.search = args[args.indexOf('--search') + 1]
275
- await cmdLoad(opts)
298
+ // Direct txid lookup — instant, no history scan
299
+ const txidIdx = args.indexOf('--txid')
300
+ if (txidIdx >= 0 && args[txidIdx + 1]) {
301
+ await cmdLoadByTxid(args[txidIdx + 1])
302
+ } else {
303
+ const opts = {}
304
+ if (args.includes('--last')) opts.last = true
305
+ if (args.includes('--search')) opts.search = args[args.indexOf('--search') + 1]
306
+ await cmdLoad(opts)
307
+ }
276
308
  } else {
277
309
  console.log(`keychat-save — Save to BSV blockchain via KeyChat (keychat.pro)
278
310
 
@@ -284,6 +316,7 @@ Commands:
284
316
  load List all saves
285
317
  load --last Most recent save
286
318
  load --search "keyword" Search saves
319
+ load --txid <txid> Load a specific save by txid (instant, no scan)
287
320
 
288
321
  Your data. Your key. Permanent on BSV.`)
289
322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keychat-save",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Save and load files to BSV blockchain via KeyChat",
5
5
  "type": "module",
6
6
  "bin": {