Add server/transactions.js

Add Fulcrum transaction lookup module
This commit is contained in:
2026-08-29 11:44:30 +00:00
parent 53b9fb183c
commit c9bd3adcb3
+185
View File
@@ -0,0 +1,185 @@
const net = require('net')
const fulcrumTimeoutMs = 3000
function queryFulcrum(fulcrumUrl, method, params = []) {
return new Promise((resolve) => {
if (!fulcrumUrl) {
resolve({
ok: false,
result: null,
error: 'Fulcrum URL is not configured',
})
return
}
let parsed
try {
parsed = new URL(fulcrumUrl)
} catch {
resolve({
ok: false,
result: null,
error: 'Invalid Fulcrum URL',
})
return
}
if (parsed.protocol !== 'tcp:') {
resolve({
ok: false,
result: null,
error: 'Fulcrum URL must use tcp://',
})
return
}
const host = parsed.hostname
const port = Number(parsed.port)
if (!host || !port) {
resolve({
ok: false,
result: null,
error: 'Fulcrum URL is missing host or port',
})
return
}
const socket = net.createConnection({
host,
port,
})
let response = ''
let settled = false
const finish = (value) => {
if (settled) {
return
}
settled = true
socket.destroy()
resolve(value)
}
socket.setTimeout(fulcrumTimeoutMs)
socket.on('connect', () => {
const request =
JSON.stringify({
jsonrpc: '2.0',
id: 1,
method,
params,
}) + '\n'
socket.write(request)
})
socket.on('data', (data) => {
response += data.toString()
const lines = response.split('\n')
for (const line of lines) {
if (!line.trim()) {
continue
}
let message
try {
message = JSON.parse(line)
} catch {
continue
}
if (message.error) {
finish({
ok: false,
result: null,
error: message.error,
})
return
}
if (
Object.prototype.hasOwnProperty.call(
message,
'result',
)
) {
finish({
ok: true,
result: message.result,
error: null,
})
return
}
}
})
socket.on('timeout', () => {
finish({
ok: false,
result: null,
error: 'Connection timed out',
})
})
socket.on('error', (error) => {
finish({
ok: false,
result: null,
error: error.message,
})
})
socket.on('close', () => {
if (!settled) {
finish({
ok: false,
result: null,
error:
'Connection closed before a response was received',
})
}
})
})
}
async function getTransaction(txid) {
if (typeof txid !== 'string' || !txid.trim()) {
throw new Error('Transaction ID is required')
}
const fulcrumUrl =
process.env.MUNIN_FULCRUM_URL || null
if (!fulcrumUrl) {
throw new Error('Fulcrum URL is not configured')
}
const result = await queryFulcrum(
fulcrumUrl,
'blockchain.transaction.get',
[txid.trim(), true],
)
if (!result.ok) {
throw new Error(
`Failed to query transaction: ${JSON.stringify(result.error)}`,
)
}
return result.result
}
module.exports = {
getTransaction,
}