Merge branch 'work/post-190-onchain-stream' into work/post-190-session-key

This commit is contained in:
archipelago
2026-10-06 06:50:55 -04:00
4 changed files with 105 additions and 15 deletions
+5 -5
View File
@@ -1288,14 +1288,14 @@ async function pollOnchain(address: string) {
timeout: 30000,
})
if (res?.paid) {
const dl = await rpcClient.call<{ data?: string; mime_type?: string; error?: string }>({
const dl = await rpcClient.call<{ data?: string; owned?: boolean; owned_content_id?: string; mime_type?: string; error?: string }>({
method: 'content.download-peer-onchain',
params: { onion, content_id: item.id, address },
timeout: 120000,
params: { onion, content_id: item.id, address, filename: item.filename, price_sats: getItemPrice(item.access), cache_only: true },
timeout: 960000,
})
onchainPaying.value = false
if (dl?.data) {
openPurchased(item, dl.data, dl.mime_type)
if (dl?.data !== undefined || dl?.owned === true) {
openPurchased(item, dl.data, dl.mime_type, onion, dl.owned_content_id)
} else {
lnError.value = dl?.error || 'Paid, but the download failed. Try again shortly.'
}
@@ -30,6 +30,21 @@ beforeEach(() => {
vi.mocked(rpcClient.payLightningInvoice).mockResolvedValue({ status: 'succeeded' } as never)
})
describe('Lightning file delivery recovery', () => {
it('opens a confirmed on-chain delivery from HTTP cache without another payment', async () => {
vi.mocked(rpcClient.call).mockImplementation(async ({ method }) => {
if (method === 'content.onchain-status') return { paid: true }
if (method === 'content.download-peer-onchain') return { owned: true, mime_type: 'video/mp4', size_bytes: 200000000 }
return { items: [] }
})
const { wrapper, vm } = await open()
await vm.pollOnchain('bc1test')
expect(vm.viewerUrl).toBe('/api/peer-content/peer.onion/paid-file')
expect(vm.viewerMime).toBe('video/mp4')
const calls = vi.mocked(rpcClient.call).mock.calls.map(([call]) => call)
expect(calls.find(call => call.method === 'content.download-peer-onchain')?.params).toMatchObject({ cache_only: true, address: 'bc1test', filename: 'bought.txt' })
expect(calls.some(call => ['lnd.sendcoins', 'content.request-onchain'].includes(call.method))).toBe(false)
wrapper.unmount()
})
it('opens a cached ecash purchase without transferring base64 into the UI', async () => {
vi.mocked(rpcClient.call).mockImplementation(async ({ method }) => {
if (method === 'content.download-peer-paid') return { owned: true, mime_type: 'video/mp4', size_bytes: 200000000 }