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.

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
npm install @tbd54566975/dwn-proxy-js
import { DwnProxy, readReq } from '@tbd54566975/dwn-proxy-js'
import type { DwnRequest, Request, Response } from '@tbd54566975/dwn-proxy-js'
const isMessageA = (dwnRequest: DwnRequest): boolean =>
dwnRequest.message.descriptor.interface === 'Records' &&
dwnRequest.message.descriptor.method === 'Query' &&
(dwnRequest.message as RecordsQueryMessage).descriptor.filter.schema === 'https://tbd.website/resources/message-a'
const isMessageB = (dwnRequest: DwnRequest): boolean =>
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: DwnRequest) {
const { id } = this.options.didState
await this.dwn.processMessage(id, request.message, request.data)
}
async handlerB(request: DwnRequest) {
await fetch('/your-backend', {
method: 'POST',
body: JSON.stringify(request)
})
}
async apiC(req: Request, res: Response) {
const body = await readReq<any>(req)
await this.client.send(body.to, body.dwnRecordsWrite, JSON.stringify(body.data))
}
async apiD(req: Request, res: Response) {
const body = await readReq<any>(req)
}
async listen(port: number) {
await super.listen(port)
this.addHandler(isMessageA, this.handlerA)
this.addHandler(isMessageB, this.handlerB)
this.server.api.post('/handler-c', this.outboundHandlerC)
this.server.api.post('/handler-d', this.apiD)
}
}
const PORT = 8080
const proxy = new MyProxy()
await proxy.listen(PORT)
new DwnProxy(options)
options
:
- (optional)
serviceEndpoint
- (optional)
didState
DwnProxy.listen(port)
Start a JSON-RPC server, hosting an HTTP server at the given port
.
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 => {
}
)
- (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) => {
res.status(200)
res.end()
})
Project Resources