Skip to content

What is pronto ?

Pronto (the word was chosen for its closeness to ontology, it also means soon in Spanish) is a core galacteek service whose role is to form a distributed graph of content through the use of linked data and peer-to-peer protocols.

Status: this system is in a testing phase

Goals

  • Explore the potential of linked data in a dynamic, P2P network
  • Define and refine LD schemas for new applications
  • Wiki-like properties for articles, pages ..
  • Censorship resistance (comes for free because of the nature of IPFS)

Technologies used

  • IPFS for storing and distributing the objects
  • JSON-LD and IPLD
  • JSON-LD signatures
  • IPS (InterPlanetary schemas) (ips is a galacteek protocol to deliver JSON-LD schemas over IPFS UnixFS, via an IPNS key)
  • RDF (Resource Data Framework)
  • SparQL (query language for RDF graphs).
  • SmartQL (galacteek protocol). This is a protocol used by the nodes in the network to synchronize graphs. This protocol is used over IPFS streams (P2P tunnels) and is based on HTTP.

How it works

Graphing the objects

Each node in the network stores the RDF graphs locally. Each node has its own objects chain.

When the user creates some content, the data is first represented as a JSON-LD object. For example this would be an article:

{
  "@type": "Article",
  "headline": "My article",
  "articleBody": "The birds are singing"
}

The object is stored first in an IPFS DAG, giving us a CID.

The DAG then goes through a process called expansion (JSON-LD expansion). The Article JSON-LD context (stored in IPFS) will be fetched and used to expand the object, converting each attribute to a fully qualified URI (headline here would be translated to ips://galacteek.ld/Article#headline).

The expanded JSON-LD can now be turned into RDF (triples), giving us the full power of linked data in a distributed environment. This RDF graph is merged in the main graph. A record of this object is stored in our chain, linking to the previous object in the chain, simply by using the record's URI (urn:ontolorecord:). Each record is signed with the RSA key of the user's DID, using JSON-LD signatures.

This is an example of an Article, in RDF:

<i:/Article/8876dc02-f09b-4cd2-bf02-a0ea2c48c98e> a gs:Article ;
    gs:articleMarkdownBody "This is a test." ;
    gs:author <i:/Person/2cbdb47f-27f6-4c95-b7ec-30ccaf442c48> ;
    gs:comesFromIpfs "/ipfs/bafyreifkas2bjr72p2igrw5dmnqlmzfffr6zjucixz7wyjctbpz36ze6cy" ;
    gs:dateCreated "2021-08-26T21:04:53.740806+00:00" ;
    gs:dateModified "2021-08-26T21:04:53.740815+00:00" ;
    gs:headline "Test" ;
    gs:inLanguage <i:/Language/English> ;
    gs:signature [ gs:created "2021-08-26T21:04:53Z" ;
            gs:signatureValue "eyJhbGciOiJSUzI1N ..." ;
            gs:type "RsaSignatureSuite2017" ] .

Syncing

Each node keeps track of all the chains in the network.

Chains are of course synced chronologically and sequentially. Notifying changes in the graphs is done via pubsub messages, followed by individual connections via IPFS streams.

Note that each node, to process and accept a new object, does the same process of expansion that the creating node did. Each node can decide if it wants to pin the underlying IPFS object or not.

Querying

Querying the graphs is simply done via SparQL. Peers run SparQL query between each other over IPFS streams (this offers great flexibility).

Dapps (like dvoz) run SparQL queries directly on the RDF graphs.

Viewing the graphs from galacteek

To explore the different graphs, open the following URLs in galacteek:

For XML exports: