What is Nostr?
librenews / Matt Terenzio
npub1vm7…3wvs
2023-10-21 13:00:27

Setting up a Nostr and Express web app (Part 1)

We’ll go through a few easy steps to get a web app up and running with Node, Express and Nostr Dev Kit.

There are lots of ways to do this. This is just a simple one, but it a highlights a couple simple changes you’ll need to get started talking to the Nostr world. Let’s set up a node project. Search install NodeJS if you need to do that first.

Jump into the terminal and create a node project:

$ mkdir mynostr
$ cd mynostr
$ npm init

You can accept all the defaults from the last command for now or add your own values.

We want to use ES modules so we’ll need to make a quick change to the package.json file that was created. add this line to it below the description:

"type": "module",

We’ll also need a way to bundle the js we need for the browser so let’s install webpack.

 npm install --save-dev webpack webpack-cli

As the title suggests we’ll leverage Express as web framework:

npm install --save express

I’m going to use Handlebars here as a template engine. I’ll probably replace it in the future with something reactive but that’s another topic.

npm install express-handlebars --save

Make a directory called views and add a file called home.handlebars to it. Add some basic HTML :

<!DOCTYPE html>
<html>
<head>
<meta  charset="utf-8">
<title>Nostr Express</title>
</head>
<body>
{{{body}}}
</body>
</html>

And add a file to the root directory called app.js

import  express  from  'express'
import { engine } from  'express-handlebars';
const app  =  express();
app.engine('handlebars', engine({ defaultLayout:  false }));
app.set('view engine', 'handlebars');
app.set('views', './views');

app.get('/', (req, res) => {
  res.render('home');
});

app.listen(3000, () => {
  console.log('listening on port 3000')
});

Let’s see how things are looking. If you are on a Mac or Linux this will do. If not you’ll have to adjust accordingly.

$ node app.js

In a browser checkout http://localhost:3000/.

We need to install he wonderful NDK (Nostr Development Kit) .

$ npm add @nostr-dev-kit/ndk

Ok, next we’ll need a way to bundle the the wonderful NDK (Nostr Development Kit) so we can access it from the browser. We already have webpack installed for that.

Create a webpack.config.js file in the root directory and add the following:

import  path  from  'path';
import { fileURLToPath } from  'url';
const  __filename  =  fileURLToPath(import.meta.url);
const  __dirname  =  path.dirname(__filename);

const  config  = {
  target:  'web',
  mode:  'production',
  entry:  './src/index.js',
  output: {
    path:  path.resolve(__dirname, 'dist'),
    filename:  'bundle.js'
  }
};

export  default  config;

We’ve used ./src/index.js as an entry point so create a directory src and a file in it called index.js containing the following:

import  NDK, { NDKNip07Signer, NDKEvent } from  "@nostr-dev-kit/ndk";
window.nip07signer  =  new  NDKNip07Signer();
window.NDK  =  NDK;

Then run:

$ npm run build

If it compiles successfully you should see a new file and directory in the project called dist/bundle.js.

We need to make this bundle available to be served to the browser so in app.js add the following lines after

import  path  from  'path';
import { fileURLToPath } from  'url';
const  __filename  =  fileURLToPath(import.meta.url);
const  __dirname  =  path.dirname(__filename);
app.use('/dist/bundle.js', express.static(__dirname  +  '/dist/bundle.js'));

Now back in your home HTML template we can verify this is all set up properly by trying to fetch a user profile from a Nostr relay by adding some JS to the head.

<script  type="module"  src="dist/bundle.js"></script>
<script type="module">
const  ndk  =  new  NDK({
  explicitRelayUrls: ["wss://relay.damus.io"],
});
await  ndk.connect();
const  user  =  await  ndk.getUser({
  npub:  "npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft",
});
user.fetchProfile().then((profile) => {
  console.log("Profile:", profile);
});
</script>

Now if you start the server again and load the page with dev tools console open you should see the JSON of the profile data was successfully fetched.

That’s it!

In Part 2 we’ll look into how we log users in, and explore some modern ways to do HMR with Vite!

Author Public Key
npub1vm7u7lzc0589m3snfpt3k5a4p4agu0t4xj5kpupzfj929ffw9yfqx63wvs