Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NOSTR_PRIVATE_KEY = YOUR_NOSTR_PRIVATE_KEY_HERE
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
.env
141 changes: 94 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ It’s built for freedom, experimentation, and creativity — turning simple cod

FreeWave listens for Nostr events that start with a prefix like:

```bash
PLAY_SONG: <song name>
```

Once received, it automatically:
1. Finds the song on YouTube.
Expand Down Expand Up @@ -48,127 +50,173 @@ Before running FreeWave, make sure you have:
## Installation Guide

### 1️⃣ Clone the Repository
``bash
```bash
git clone https://github.com/<your-username>/FreeWave.git
cd FreeWave
```

2️⃣ Install Dependencies

### 2️⃣ Install Dependencies
```
npm install
npm install dotenv
```

3️⃣ Install System Tools
### 3️⃣ Install System Tools

Ubuntu / Debian
### i) Ubuntu / Debian

```bash
sudo apt update
sudo apt install mpv
pip install yt-dlp
```

macOS
### ii) macOS

```bash
brew install mpv yt-dlp
```

Windows
### iii) Windows

Install Node.js from nodejs.org
Install `Node.js` from [nodejs.org](https://nodejs.org/en)

Download yt-dlp.exe and mpv.exe, and add both to PATH

### 4️⃣ Setup Your Nostr Private Key

#### Step 1 — Generate a private key

In Node.js:
```bash
node
> const { generateSecretKey, getPublicKey } = await import("nostr-tools");
> const sk = generateSecretKey();
> console.log("PRIVATE KEY (hex):", sk);
> console.log("PUBLIC KEY:", getPublicKey(sk));
```

#### Step 2 — Save it in a .env file
FreeWave never stores your key in code. Use an environment variable instead.

Rename the `.env.example` file to `.env`. You can find it in the project root folder.
```bash
FreeWave/
├── scripts/
│ ├── send-song-command.mjs
│ └── listen-and-play-song.mjs
├── package.json
├── .gitignore
├── .env.example
└── README.md
```

Then, on the `.env` file, replace `YOUR_NOSTR_PRIVATE_KEY_HERE` with your nost private key

#### Step 3 — Verify

```bash
node -e "import('dotenv/config'); console.log(process.env.NOSTR_PRIVATE_KEY)"
```
You should see your 64-character hex key printed.

Exporting Your Keys
### 5. Exporting Your Keys

To protect privacy, FreeWave never stores your keys directly inside the script.
Instead, export them as environment variables.

Example:

```bash
export NOSTR_PRIVKEY_HEX="your_private_key_here"
```

If you only have an nsec key, you can convert it to hex:

```bash
node
> const { nip19 } = await import("nostr-tools");
> const result = nip19.decode("nsec1yourkeyhere");
> console.log(Buffer.from(result.data).toString("hex"));
```

Then export the result again:

```bash
export NOSTR_PRIVKEY_HEX="converted_hex_key_here"
```

Now your scripts can access it automatically!




Usage
## Usage

Send a Song Command

```bash
npm run send-song "Blinding Lights by The Weeknd"
```

Start the Listener

```bash
npm run start-listener
```

FreeWave will automatically detect your Nostr commands, download, play, and clean up after itself.



Folder Structure

#### Folder Structure:
```bash
FreeWave/
├── scripts/
│ ├── send-song-command.mjs
│ └── listen-and-play-song.mjs
├── package.json
├── .gitignore
└── README.md
```




Gadgets & Hardware Setup (Optional)
## Gadgets & Hardware Setup (Optional)

You can go beyond the terminal — build your own FreeWave Node!

Gadget Purpose / Use
| Gadget | Purpose / Use |
|---------------------------|--------------------------------------------------|
| Old Android Phone | Run FreeWave via Termux or Node.js as a portable Nostr node |
| Raspberry Pi (3 or 4) | 24/7 listener connected to a speaker or display |
| Arduino (ESP32 / ESP8266) | Control LEDs, buttons, or visual indicators |
| OLED / LCD Display | Show current track name, artist, or connection status |
| Bluetooth Speaker | Wireless music playback |
| RGB LEDs or Neopixels | Flash, pulse, or animate with the beat |
| Powerbank or UPS | Run your setup off-grid |
| WiFi Dongle / Ethernet | Ensure a stable connection |
| Buttons / Rotary Knob | Control play, pause, or skip directly |
| Mini Amplifier (PAM8403) | Boost small speaker setups |
| 3D-Printed Case | Make your node look like a futuristic jukebox |

Old Android Phone Run FreeWave via Termux or Node.js as a portable Nostr node
Raspberry Pi (3 or 4) 24/7 listener connected to a speaker or display
Arduino (ESP32 / ESP8266) Control LEDs, buttons, or visual indicators
OLED / LCD Display Show current track name, artist, or connection status
Bluetooth Speaker Wireless music playback
RGB LEDs or Neopixels Flash, pulse, or animate with the beat
Powerbank or UPS Run your setup off-grid
WiFi Dongle / Ethernet Ensure a stable connection
Buttons / Rotary Knob Control play, pause, or skip directly
Mini Amplifier (PAM8403) Boost small speaker setups
3D-Printed Case Make your node look like a futuristic jukebox




How to Make It Interactive
## How to Make It Interactive

Want to bring your FreeWave to life?

Use an ESP32 board to detect song events and light up LEDs.
- Use an ESP32 board to detect song events and light up LEDs.

Add an OLED display to show track titles and relay names.
- Add an OLED display to show track titles and relay names.

Control playback with buttons using simple serial commands.
- Control playback with buttons using simple serial commands.


Your FreeWave becomes a smart, physical music player powered by Nostr!

### package.json (For Reference)

---

package.json (For Reference)

```bash
{
"name": "freewave",
"version": "1.0.0",
Expand All @@ -186,30 +234,29 @@ Your FreeWave becomes a smart, physical music player powered by Nostr!
"nostr-tools": "^2.17.2"
}
}
```



Contributing
## Contributing

FreeWave is community-built — feel free to fork, open issues, or submit pull requests!

Ideas welcome:

Add a GUI or web dashboard
## Ideas welcome:

Add LED sync effects
- Add a GUI or web dashboard

Integrate more Nostr event types
- Add LED sync effects

Create themed hardware builds
- Integrate more Nostr event types

- Create themed hardware builds



Credits
## Credits

Developed by Martin Arts & contributors
Powered by Nostr, yt-dlp, and mpv
Powered by `Nostr`, `yt-dlp`, and `mpv`

> “Let the music flow freely across the network — this is the wave of sound, not control.”

Expand Down
3 changes: 2 additions & 1 deletion scripts/send-song-command.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// send-song-command.mjs
import { Relay, getPublicKey, finalizeEvent } from "nostr-tools";
import 'dotenv/config';

// ----------------- YOUR HEX PRIVATE KEY -----------------
const myHexPrivKey = "<Your hex key>";
const myHexPrivKey = process.env.NOSTR_PRIVATE_KEY;
// --------------------------------------------------------

// Get public key directly from hex
Expand Down