Journey into Web Monetization - day 3
Carl Barrdahl
Posted on May 12, 2020
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 variableILP_BTP_SERVER
and defaults tobtp+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
andsharedSecret
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
π πͺ π
π©
Carl Barrdahl
Posted on May 12, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
gftwhackathon Grant for the Web Sponsors 3 $1000 Hacker Noon Noonie Awards for Web Monetization
August 7, 2020