@tbd54566975/dwn-proxy-js
TypeScript icon, indicating that this package has built-in type declarations

0.0.5 • Public • Published

DWN Proxy

Making DWN integrations with traditional backend services easy.

⚠️ UNDER DEVELOPMENT ⚠️

dwn-proxy-js is a bidirectional proxy between Decentralized Web Nodes and your web services.

Intro diagram

Design

At it's lightest, this package can act as a network router for DWN Message's. At it's heaviest, this package can be used to selectively abstract DWN-concepts from your web services. You have optionality as to the degree to which you differentiate across the two network interfaces.

Like the dwn-server, this package is intended to be used server-side, wherein DWN Messages are interfaced with via JSON-RPC (compatible with web5-js's Agent interface). However, unlike dwn-server, this package offers a programmatic interface for handling DWN Messages, both inbound and outbound, with the design intent of integrating with traditional backend services.

Usage

In a new directory, run:

npm init -y
npm install @tbd54566975/dwn-proxy-js

Then edit the package.json to have "type":"module" in it.

Add a file called index.js with the following contents:

import { DwnProxy, readReq } from '@tbd54566975/dwn-proxy-js';
const isMessageA = (dwnRequest) => dwnRequest.message.descriptor.interface === 'Records' &&
    dwnRequest.message.descriptor.method === 'Query' &&
    dwnRequest.message.descriptor.filter.schema === 'https://tbd.website/resources/message-a';
const isMessageB = (dwnRequest) => dwnRequest.message.descriptor.interface === 'Records' &&
    dwnRequest.message.descriptor.method === 'Write' &&
    dwnRequest.message.descriptor.schema === 'https://tbd.website/resources/message-b';
class MyProxy extends DwnProxy {
    async handlerA(request) {
        // do whatever you want
        // ...
        // example: maybe process the message using the DWN instance
        const { id } = this.options.didState;
        await this.dwn.processMessage(id, request.message, request.payload);
    }
    async handlerB(request) {
        // do whatever you want
        // ...
        // example: maybe forward the request onto your backend
        await fetch('/your-backend', {
            method: 'POST',
            body: JSON.stringify(request)
        });
    }
    async apiC(req, res) {
        const body = await readReq(req);
        // do whatever you want
        // ...
        // maybe send the message onto a user
        await this.client.send(body.to, body.dwnRecordsWrite, JSON.stringify(body.data));
    }
    async apiD(req, res) {
        const body = await readReq(req);
        // do whatever you want
        // ...
    }
    // overriding the default DwnProxy.listen()
    async listen(port) {
        await super.listen(port);
        // wire-up your dwn handlers
        this.addHandler(isMessageA, this.handlerA);
        this.addHandler(isMessageB, this.handlerB);
        // wire-up your server handlers
        this.server.api.post('/handler-c', this.apiC);
        this.server.api.post('/handler-d', this.apiD);
    }
}
const PORT = 8080;
const proxy = new MyProxy({});
await proxy.listen(PORT);
node index.js

And you have a proxy running!

new DwnProxy(options)

  • options:
    • (optional) serviceEndpoint
    • (optional) didState

DwnProxy.listen(port)

Start a JSON-RPC server, hosting an HTTP server at the given port.

  • (required) port: number

DwnProxy.addHandler(match, handler)

Add a handler for inbound DWN Messages.

const isMyMessage = req => 
  req.message.descriptor.interface === 'Records' &&
  req.message.descriptor.method === 'Write' &&
  req.message.descriptor.schema === 'https://your-schema/file.json'
proxy.addHandler(
  isMyMessage,
  async req => {
    // do whatever you would like with the given DwnRequest
  }
)
  • (required) match: (req: DwnRequest) => boolean
    • if evaluated to true then use handler for the given message
  • (required) handler: (dwnRequest: DwnRequest) => Promise<void | DwnResponse>
    • if return type is void then the underlying DwnHttpServer will call dwn.processMessage() whereafter it will respond to the client w/ the given result
    • Else, you can explicitly specify your DwnResponse which will not result in a subsequent call to dwn.processMessage()

DwnProxy.server.api

Directly interface with the Express server

proxy.server.api.post('/some-outbound-api', async (req, res) => {
  // do whatever you would like 

  res.status(200)
  res.end()
})

Project Resources

Resource Description
CODEOWNERS Outlines the project lead(s)
CODE_OF_CONDUCT.md Expected behavior for project contributors, promoting a welcoming environment
CONTRIBUTING.md Developer guide to build, test, run, access CI, chat, discuss, file issues
GOVERNANCE.md Project governance
LICENSE Apache License, Version 2.0

Package Sidebar

Install

npm i @tbd54566975/dwn-proxy-js

Weekly Downloads

42

Version

0.0.5

License

Apache-2.0

Unpacked Size

80.8 kB

Total Files

29

Last publish

Collaborators

  • tbd-releases
  • kendallweihe
  • shamilovtim
  • frankhinek
  • michaelneale
  • csuwildcat
  • mistermoe
  • alrubinger
  • nitroneal
  • mktbd
  • henrytsai