backup commit
This commit is contained in:
@@ -1275,6 +1275,236 @@ app.post('/rpc/v1', (req, res) => {
|
||||
return res.json({ result: [] })
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Mesh Networking (LoRa radio via Meshcore)
|
||||
// =====================================================================
|
||||
case 'mesh.status': {
|
||||
return res.json({
|
||||
result: {
|
||||
enabled: true,
|
||||
device_type: 'Meshcore',
|
||||
device_path: '/dev/ttyUSB0',
|
||||
device_connected: true,
|
||||
firmware_version: '2.3.1',
|
||||
self_node_id: 42,
|
||||
self_advert_name: 'archy-228',
|
||||
peer_count: 4,
|
||||
channel_name: 'archipelago',
|
||||
messages_sent: 23,
|
||||
messages_received: 47,
|
||||
detected_devices: ['/dev/ttyUSB0'],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'mesh.peers': {
|
||||
return res.json({
|
||||
result: {
|
||||
peers: [
|
||||
{
|
||||
contact_id: 1,
|
||||
advert_name: 'archy-198',
|
||||
did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2ReMkBe4bR6XBIDNq9',
|
||||
pubkey_hex: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2',
|
||||
rssi: -67,
|
||||
snr: 9.5,
|
||||
last_heard: new Date(Date.now() - 30000).toISOString(),
|
||||
hops: 0,
|
||||
},
|
||||
{
|
||||
contact_id: 2,
|
||||
advert_name: 'satoshi-relay',
|
||||
did: 'did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH',
|
||||
pubkey_hex: 'f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5',
|
||||
rssi: -82,
|
||||
snr: 4.2,
|
||||
last_heard: new Date(Date.now() - 120000).toISOString(),
|
||||
hops: 1,
|
||||
},
|
||||
{
|
||||
contact_id: 3,
|
||||
advert_name: 'mountain-node',
|
||||
did: null,
|
||||
pubkey_hex: null,
|
||||
rssi: -95,
|
||||
snr: 1.8,
|
||||
last_heard: new Date(Date.now() - 600000).toISOString(),
|
||||
hops: 2,
|
||||
},
|
||||
{
|
||||
contact_id: 4,
|
||||
advert_name: 'bunker-alpha',
|
||||
did: 'did:key:z6MkrHKPxJP6tvCvXMaJKZd3rRA2Y44tyftVhR8FDCMKGFjb',
|
||||
pubkey_hex: 'c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
|
||||
rssi: -74,
|
||||
snr: 7.1,
|
||||
last_heard: new Date(Date.now() - 45000).toISOString(),
|
||||
hops: 0,
|
||||
},
|
||||
],
|
||||
count: 4,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'mesh.messages': {
|
||||
const limit = params?.limit || 100
|
||||
const now = Date.now()
|
||||
const allMessages = [
|
||||
{ id: 1, direction: 'received', peer_contact_id: 1, peer_name: 'archy-198', plaintext: 'Node online. Bitcoin Knots synced to tip.', timestamp: new Date(now - 3600000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 2, direction: 'sent', peer_contact_id: 1, peer_name: 'archy-198', plaintext: 'Good. Electrs index at 98%. Channel capacity 2.5M sats.', timestamp: new Date(now - 3540000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 3, direction: 'received', peer_contact_id: 2, peer_name: 'satoshi-relay', plaintext: 'ARCHY:2:a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2:d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5', timestamp: new Date(now - 3000000).toISOString(), delivered: true, encrypted: false },
|
||||
{ id: 4, direction: 'received', peer_contact_id: 1, peer_name: 'archy-198', plaintext: 'Federation state sync complete. 3 containers matched.', timestamp: new Date(now - 1800000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 5, direction: 'sent', peer_contact_id: 4, peer_name: 'bunker-alpha', plaintext: 'Running mesh-only mode. No internet for 48h. All good.', timestamp: new Date(now - 900000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 6, direction: 'received', peer_contact_id: 4, peer_name: 'bunker-alpha', plaintext: 'Copy. Block height 890,412 via compact headers. 6 confirmations on last tx.', timestamp: new Date(now - 840000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 7, direction: 'received', peer_contact_id: 2, peer_name: 'satoshi-relay', plaintext: 'New block relayed: 890,413. Fees averaging 12 sat/vB.', timestamp: new Date(now - 600000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 8, direction: 'sent', peer_contact_id: 1, peer_name: 'archy-198', plaintext: 'Opening 1M sat channel to your node. Approve?', timestamp: new Date(now - 300000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 9, direction: 'received', peer_contact_id: 1, peer_name: 'archy-198', plaintext: 'Approved. Waiting for funding tx confirmation.', timestamp: new Date(now - 240000).toISOString(), delivered: true, encrypted: true },
|
||||
{ id: 10, direction: 'received', peer_contact_id: 3, peer_name: 'mountain-node', plaintext: 'Anyone copy? Solar panel restored, back online.', timestamp: new Date(now - 120000).toISOString(), delivered: true, encrypted: false },
|
||||
{ id: 11, direction: 'sent', peer_contact_id: 3, peer_name: 'mountain-node', plaintext: 'Copy mountain-node. Welcome back. Relaying your backlog.', timestamp: new Date(now - 60000).toISOString(), delivered: true, encrypted: false },
|
||||
{ id: 12, direction: 'received', peer_contact_id: 4, peer_name: 'bunker-alpha', plaintext: 'Dead man switch check-in. All systems nominal. Battery 78%.', timestamp: new Date(now - 30000).toISOString(), delivered: true, encrypted: true },
|
||||
]
|
||||
return res.json({
|
||||
result: {
|
||||
messages: allMessages.slice(0, limit),
|
||||
count: allMessages.length,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'mesh.send': {
|
||||
const contactId = params?.contact_id
|
||||
const message = params?.message || ''
|
||||
const peer = [
|
||||
{ id: 1, name: 'archy-198', encrypted: true },
|
||||
{ id: 2, name: 'satoshi-relay', encrypted: true },
|
||||
{ id: 3, name: 'mountain-node', encrypted: false },
|
||||
{ id: 4, name: 'bunker-alpha', encrypted: true },
|
||||
].find(p => p.id === contactId)
|
||||
console.log(`[Mesh] Send to ${peer?.name || contactId}: ${message}`)
|
||||
return res.json({
|
||||
result: {
|
||||
sent: true,
|
||||
message_id: Math.floor(Math.random() * 10000) + 100,
|
||||
encrypted: peer?.encrypted ?? false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'mesh.broadcast': {
|
||||
console.log('[Mesh] Broadcasting identity over LoRa')
|
||||
return res.json({ result: { broadcast: true } })
|
||||
}
|
||||
|
||||
case 'mesh.configure': {
|
||||
console.log(`[Mesh] Configure:`, params)
|
||||
return res.json({ result: { configured: true } })
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Transport Layer (unified routing: mesh > lan > tor)
|
||||
// =====================================================================
|
||||
case 'transport.status': {
|
||||
return res.json({
|
||||
result: {
|
||||
transports: [
|
||||
{ kind: 'mesh', available: true },
|
||||
{ kind: 'lan', available: true },
|
||||
{ kind: 'tor', available: true },
|
||||
],
|
||||
mesh_only: false,
|
||||
peer_count: 5,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'transport.peers': {
|
||||
return res.json({
|
||||
result: {
|
||||
peers: [
|
||||
{
|
||||
did: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2ReMkBe4bR6XBIDNq9',
|
||||
pubkey_hex: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2',
|
||||
name: 'archy-198',
|
||||
trust_level: 'trusted',
|
||||
mesh_contact_id: 1,
|
||||
lan_address: '192.168.1.198:5678',
|
||||
onion_address: 'peer1abc2def3ghi4jkl5mno6pqr7stu8vwx9yz.onion',
|
||||
preferred_transport: 'lan',
|
||||
available_transports: ['mesh', 'lan', 'tor'],
|
||||
last_seen: new Date(Date.now() - 30000).toISOString(),
|
||||
},
|
||||
{
|
||||
did: 'did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH',
|
||||
pubkey_hex: 'f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3b2a1f6e5',
|
||||
name: 'satoshi-relay',
|
||||
trust_level: 'trusted',
|
||||
mesh_contact_id: 2,
|
||||
lan_address: null,
|
||||
onion_address: 'peer2xyz9wvu8tsr7qpo6nml5kji4hgf3edc2ba.onion',
|
||||
preferred_transport: 'mesh',
|
||||
available_transports: ['mesh', 'tor'],
|
||||
last_seen: new Date(Date.now() - 120000).toISOString(),
|
||||
},
|
||||
{
|
||||
did: 'did:key:z6MkrHKPxJP6tvCvXMaJKZd3rRA2Y44tyftVhR8FDCMKGFjb',
|
||||
pubkey_hex: 'c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
|
||||
name: 'bunker-alpha',
|
||||
trust_level: 'observer',
|
||||
mesh_contact_id: 4,
|
||||
lan_address: null,
|
||||
onion_address: null,
|
||||
preferred_transport: 'mesh',
|
||||
available_transports: ['mesh'],
|
||||
last_seen: new Date(Date.now() - 45000).toISOString(),
|
||||
},
|
||||
{
|
||||
did: 'did:key:z6MkjchhfUsD6mmvni8mCdXHw216Xrm9bQe2mBH1P5RDjVJG',
|
||||
pubkey_hex: 'd4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5',
|
||||
name: 'office-node',
|
||||
trust_level: 'trusted',
|
||||
mesh_contact_id: null,
|
||||
lan_address: '192.168.1.42:5678',
|
||||
onion_address: 'peer4mno6pqr7stu8vwx9yzabc2def3ghi4jkl5.onion',
|
||||
preferred_transport: 'lan',
|
||||
available_transports: ['lan', 'tor'],
|
||||
last_seen: new Date(Date.now() - 60000).toISOString(),
|
||||
},
|
||||
{
|
||||
did: 'did:key:z6MknGc3ocHs3zdPiJbnaaqDi58NGb4pk1Sp7NQD5EjEREWh',
|
||||
pubkey_hex: 'e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6',
|
||||
name: 'remote-cabin',
|
||||
trust_level: 'trusted',
|
||||
mesh_contact_id: null,
|
||||
lan_address: null,
|
||||
onion_address: 'peer5xyz9abc2def3ghi4jkl5mno6pqr7stu8vw.onion',
|
||||
preferred_transport: 'tor',
|
||||
available_transports: ['tor'],
|
||||
last_seen: new Date(Date.now() - 300000).toISOString(),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'transport.send': {
|
||||
const targetDid = params?.did
|
||||
console.log(`[Transport] Send to ${targetDid} via best transport`)
|
||||
return res.json({
|
||||
result: {
|
||||
sent: true,
|
||||
transport_used: 'mesh',
|
||||
did: targetDid,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
case 'transport.set-mode': {
|
||||
const meshOnly = params?.mesh_only ?? false
|
||||
console.log(`[Transport] Set mesh_only mode: ${meshOnly}`)
|
||||
return res.json({ result: { mesh_only: meshOnly, configured: true } })
|
||||
}
|
||||
|
||||
default: {
|
||||
console.log(`[RPC] Unknown method: ${method}`)
|
||||
return res.json({
|
||||
|
||||
Reference in New Issue
Block a user