This repository has been archived on 2025-01-14. You can view files and clone it, but cannot push or open issues or pull requests.

143 lines
4.5 KiB
JavaScript

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');
});
}