DEV Community

Carl Barrdahl
Carl Barrdahl

Posted on

14 7

Journey into Web Monetization - day 3

After the first day of idea generation and the second day of learning, I thought I'd get into the more practial side of it and try to get something up to play around with.

Here's what I did:

  • Connect to a Interledger testnet with moneyd
  • Create an ILP stream server to connect to the moneyd instance.
  • Generate stream credentials and send money

Run npx moneyd local to start the moneyd instance with a local testnet.

Next, set up a simple node project:

npm init -y
npm i -S ilp-protocol-stream ilp-plugin @interledger/connection-tag-utils
mkdir src
touch src/index.js
// src/index.js
const { randomBytes } = require("crypto");
const { createServer, createConnection } = require("ilp-protocol-stream");
const { encode, decode } = require("@interledger/connection-tag-utils");
const createPlugin = require("ilp-plugin");

// Used for encoding and decoding connectionTag
const SECRET_KEY = randomBytes(32);

async function createStreamServer() {
  const server = await createServer({ plugin: createPlugin() });
  server.on("connection", (connection) => {
    // connectionTag contains encrypted data, in this case about the user account
    const { account } = JSON.parse(
      decode(SECRET_KEY, connection.connectionTag)
    );
    connection.on("stream", (stream) => {
      stream.setReceiveMax(10000);
      stream.on("money", (amount) => {
        console.log(`Received payment from ${account} for: ${amount}`);
      });
    });
  });

  return server;
}

async function sendMoney({ amount, destinationAccount, sharedSecret }) {
  const connection = await createConnection({
    plugin: createPlugin(),
    destinationAccount,
    sharedSecret,
  });

  const stream = connection.createStream();
  await stream.sendTotal(amount);
  await connection.end();
}

async function run() {
  const server = await createStreamServer();

  // Encode the user account here so we can use when we receive money
  const data = encode(SECRET_KEY, JSON.stringify({ account: "userAccountId" }));

  const { destinationAccount, sharedSecret } = server.generateAddressAndSecret(
    data
  );

  const amount = 10000;
  await sendMoney({ amount, destinationAccount, sharedSecret });
  await server.close();
}

run().catch((err) => console.log(err));

And finally run it:

npx nodemon src/index.js

Received payment from userAccountId for: 10000
  • Plugins such as ilp-plugin determines where the server connects. It looks for env variable ILP_BTP_SERVER and defaults to btp+ws://localhost:7768 if not found. This is the local moneyd instance.
  • Data such as information about user or invoice can be encoded in the connectionTag. This will allow us to update databases for example.
  • To create a stream client and send money we need: destinationAccount and sharedSecret which we can get from a server.

Possible next steps

  • Connect to a non-local testnet
  • Send money between other wallets
  • Build a REST server and handle different users and payment pointers
  • Build a browser extension to handle the functionality currently in sendMoney

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay