const WebSocket = require('ws'); const crypto = require('crypto'); const elliptic = require('elliptic'); const Buffer = require('safe-buffer').Buffer const schnorr = require('bip-schnorr'); const settings = require('./settings.json'); // Use elliptic for ECDSA signing const EC = elliptic.ec; const ecdsa = new EC('secp256k1'); // Your Nostr private key (replace with your own) const privateKeyHex = settings.secretKey; // Use your actual private key here // Ensure private key is a valid 32-byte hex string if (!/^([0-9a-fA-F]{64})$/.test(privateKeyHex)) { console.error('Invalid private key format. Ensure it is 64 hexadecimal characters.'); process.exit(1); } const publicKeyHex = generatePublicKey(privateKeyHex); // Connect to Binance WebSocket const ws = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt@ticker'); // Handle WebSocket connection and data ws.on('open', function open() { console.log('Connected to Binance WebSocket'); }); ws.on('message', function incoming(message) { const data = JSON.parse(message); // Extract relevant data const symbol = data.s; const lastPrice = parseFloat(data.c); const weightedAvgPrice = parseFloat(data.w); const highPrice = parseFloat(data.h); const lowPrice = parseFloat(data.l); // Create Nostr event const timestamp = Math.floor(Date.now() / 1000); const eventContent = JSON.stringify({ symbol, last_price: lastPrice, weighted_avg_price: weightedAvgPrice, high_price: highPrice, low_price: lowPrice }); const event = { id: '', pubkey: publicKeyHex, // 32-byte public key created_at: timestamp, kind: 31892, // Note (you can change this based on your event type) tags: [['d','BTCUSD'],['n', 'BTC','USD'],['value', 'lastPrice']], // Optional tag (you can customize this) content: eventContent, sig: '' // Initialize sig here, it will be added after content }; // Compute event ID (sha256 of serialized event) const serializedEvent = serializeEvent(publicKeyHex, timestamp, event.kind, event.tags, eventContent); const eventId = crypto.createHash('sha256').update(serializedEvent).digest('hex'); event.id = eventId; // Sign the event using elliptic library event.sig = signEvent(privateKeyHex, serializedEvent, event.id); // Print the Nostr event with signature under content console.log('Nostr Event:', JSON.stringify(event, null, 2)); // Optionally, broadcast the event to a Nostr relay (example) sendToRelay(event); }); // Function to generate compressed public key from private key using elliptic function generatePublicKey(privateKeyHex) { const privateKey = Buffer.from(privateKeyHex, 'hex'); if (privateKey.length !== 32) { console.error('Private key must be 32 bytes.'); process.exit(1); } const key = ecdsa.keyFromPrivate(privateKey); const publicKey = key.getPublic(true, 'hex'); // Compressed format return publicKey.slice(2); // Remove the '0x' prefix to get 32 bytes } // Function to serialize the event according to NIP-01 function serializeEvent(pubkey, createdAt, kind, tags, content) { const eventData = [ 0, // Prefix for NIP-01 event serialization pubkey, createdAt, kind, tags, content ]; // Serialize the event to JSON string let eventJson = JSON.stringify(eventData, (key, value) => { // Escape content field (you can also add custom escaping here if necessary) if (key === 'content') { value = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); } return value; }); return eventJson; } // Function to sign the event with the private key using elliptic function signEvent(privateKeyHex, serializedEvent, eventID) { const message = Buffer.from(eventID, 'hex'); const signature = schnorr.sign(privateKeyHex, message); return signature.toString('hex'); } // Function to send the event to a Nostr relay function sendToRelay(event) { // Example relay URL (replace with the actual Nostr relay URL) const relayUrl = settings.relayUri; // Replace with your relay URL // Create a WebSocket connection to the relay const relayWs = new WebSocket(relayUrl); relayWs.on('open', () => { // Once the connection is open, send the event const eventMessage = ['EVENT', event]; // Relay expects an array with 'EVENT' and event data relayWs.send(JSON.stringify(eventMessage)); console.log('Event sent to relay:', JSON.stringify(event, null, 2)); }); relayWs.on('error', (err) => { console.error('Error sending event to relay:', err); }); relayWs.on('close', () => { console.log('Connection to relay closed'); }); }