Skip to content

❇️ A JSON-WSP WebSocket bridge for cardano-node

License

Notifications You must be signed in to change notification settings

psychomb/cardano-ogmios

 
 

Repository files navigation

ogmios

Overview

Ogmios is a translation service written in Haskell running on top of cardano-node. It offers a JSON-WSP interface through WebSockets and enables clients to speak Ouroboros' mini-protocols via remote procedure calls over JSON.

            CARDANO RELAY                                     OGMIOS SERVER   
                                                                           
                  ◦                                                _=_       
<-------->    ◦   ○   ◦                                          q(-_-)p     
               ○ ◯ ◯ ○                                            _\=/_      
<--------> ◦ ○ ◯     ◯ ○ ◦  <----Mini-Protocols / CBOR---->      /     \     <----WebSocket / JSON---->
               ○ ◯ ◯ ○                                         _(<\   />)_   
<-------->    ◦   ○   ◦                                       (__\_\_/_/__)  
                  ◦

Ouroboros' mini-protocols are described as state-machines. Ogmios currently supports the following mini protocols:

Chain Synchronisation Protocol
 *-----------*                                              | Clients wishing to synchronise blocks from
 | Intersect |◀══════════════════════════════╗              | the chain can use the Chain Sync protocol.
 *-----------*         FindIntersect         ║              | 
       │                                     ║              | The protocol is stateful, which means that
       │                                *---------*         | each connection between clients and ogmios
       │ Intersect.{Found,NotFound}     |         |         | has a state: a  cursor locating a point on
       └───────────────────────────────╼|         |         | the chain.
                                        |   Idle  |         | 
    ╔═══════════════════════════════════|         |         | Typically, a client will  start by looking
    ║            RequestNext            |         |⇦ START  | for an intersection  between its own local
    ║                                   *---------*         | chain and  the one from the  node / ogmios.
    ▼                                        ╿              |  
 *------*       Roll.{Backward,Forward}      │              | Then, it'll simply request the next action
 | Next |────────────────────────────────────┘              | to take: either rolling forward and adding
 *------*                                                   | new blocks, or rolling backward.
Local Transaction Submission Protocol
 *----------*                                                | Transaction submission is pretty simple &
 |   Busy   |◀══════════════════════════════╗                | works by submitting an already serialized 
 *----------*            SubmitTx           ║                | and signed UTxO transaction as one single
      │                                     ║                | message. 
      │                                *---------*           | 
      │                                |         |           | In case of  success, the server returns an
      │                                |         |           | empty  response. Otherwise, it  returns an
      │          SubmitTxResponse      |   Idle  |           | error  with some details  about what  went 
      └───────────────────────────────╼|         |           | wrong.
                                       |         |⇦ START    |
                                       *---------*           | Clients must thereby know how to construct
                                                             | valid transactions.

Why Bother?

Ogmios brings the Ouroboros mini-protocols to the Web, effectively allowing light clients to interact with a relay node in a very simple and efficient way. Ogmios is very lightweight too and can be deployed alongside relays to create entry points on the Cardano network for various type of applications (e.g. wallets, explorers, chatbots, dashboards...).

Getting Started

DockerHub Badge

🐳 docker-compose up

☝️ This will run and connect together:

  • An OBFT Byron cardano-node, connected to MainNet.
  • An Ogmios server, listening to localhost on port :1337.

And here-under are a few JavaScript snippets of client code interacting with a local Ogmios server.

skeleton.js
/*
 * Typical skeleton code for interacting with Ogmios.
 */

const socket = new WebSocket("ws://HOST:PORT");

const method = {
  FindIntersect: "FindIntersect",
  RequestNext: "RequestNext",
  SubmitTx: "SubmitTx"
};

socket.onopen = function (event) {
    socket.wsp(method.FindIntersect, { points: ["origin"] })
};

socket.onmessage = function (event) {
  let msg = JSON.parse(event.data);

  switch (msg.methodname) {
    case method.FindIntersect:
      // do something
    break;

    case method.RequestNext:
      // do something
    break;

    case method.SubmitTx: 
      // do something
    break;
  }

  socket.wsp(method.RequestNext);
};

// ---------------- See also `WebSocket-polyfill.js`
simple-client.js
/* 
 * A simple client which fetches the first 100 blocks of the chain and print 
 * them to the console.
 */

const socket = new WebSocket("ws://localhost:1337");
// Or, alternatively: const socket = new WebSocket("wss://ogmios.dev");

const methods = {
  FindIntersect: "FindIntersect",
  RequestNext: "RequestNext"
};

let n = 100;

socket.onopen = function (event) {
    socket.wsp(methods.FindIntersect, { points: ["origin"] })
};

socket.onmessage = function (event) {
  let msg = JSON.parse(event.data);
  console.log(msg.result);
  if (n > 0) {
    socket.wsp(methods.RequestNext);
    n--;
  } else {
    socket.close();
  }
};

socket.onclose = function (event) {
  console.log("Connection closed.");
};

// ---------------- See also `WebSocket-polyfill.js`
WebSocket-polyfill.js
  /* A simple helper to facilitate JSON-WSP requests through a browser WebSocket. 
  */
  WebSocket.prototype.wsp = function wsp(methodname, args = {}, mirror = null) {
    this.send(JSON.stringify({
      type: "jsonwsp/request",
      version: "1.0",
      methodname,
      args,
      mirror
    }));
  }

📖 API Reference | 💻 Command-Line Interface | 📦 Deployment Guide | 🎁 Contributing | 💾 Changelog

About

❇️ A JSON-WSP WebSocket bridge for cardano-node

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Haskell 96.3%
  • Dockerfile 2.0%
  • HTML 1.4%
  • Shell 0.3%