p2panda / aquadoggo

Node for the p2panda network handling validation, storage, aggregation and replication
GNU Affero General Public License v3.0
69 stars 5 forks source link
graphql libp2p local-first node p2p

aquadoggo

p2panda network node


CI Status Codecov Report Crates.io version

Docs | Releases | Contribute | Website


aquadoggo is a reference node implementation for p2panda. It is a intended as a tool for making the design and build of local-first, collaborative p2p applications as simple as possible, and hopefully even a little fun!

aquadoggo can run both on your own device for local-first applications, or on a public server when acting as shared community infrastructure. Nodes like aquadoggo perform a number of tasks ranging from core p2panda data replication and validation, aiding the discovery and establishment of connections between edge peers, and exposing a developer friendly API used for building applications.

Features

Who is this for?

aquadoggo might be interesting for anyone who wants to participate in a p2p network. This could be as a node maintainer, an application developer or simply someone wanting to learn more about p2p networking in a hands-on fashion.

If you are familiar with (or are keen to learn) how to use command line interfaces then you're able to deploy a node on your own machine, you can then experiment with creating data schemas, publishing and replicating data, and then querying it again using the GraphQL playground. Check out the resources section for ideas on next steps when you're ready.

What can I build with this?

Many applications which rely on being able to store and retrieve data from a persistent store could likely be built using aquadoggo as their data layer. aquadoggo can be considered as a p2p "backend", which takes some of the complexity out of p2p development, leaving you to focus on building applications using your preferred tools.

If you want to build a client application which communicates with an aquadoggo you will need to have some experience with web development or the Rust programming language. For writing an application using Rust you can import aquadoggo directly in your code. If building a TypeScript web frontend which will interface with a local or remote node, you can import the small TypeScript client library shirokuma to your project. We have plans for making it easier to interact with aquadoggo using other languages in the future.

Some example applications which could be built on top of aquadoggo are:

We're excited to hear about your ideas! Join our official chat and reach out.

Installation

Command line application

Check out our Releases section where we publish binaries for Linux, RaspberryPi, MacOS and Windows or read how you can compile aquadoggo yourself.

Rust Crate

For using aquadoggo in your Rust project, you can add it as a dependency with the following command:

cargo add aquadoggo

Usage

Run node

You can also run the node simply as a command line application. aquadoggo can be configured in countless ways for your needs, read our configuration section for more examples, usecases and an overview of configuration options.

# Start a local node on your machine, go to http://localhost:2020/graphql for using the GraphQL playground
aquadoggo

# Check out all configuration options
aquadoggo --help

# Enable logging
aquadoggo --log-level info

Docker

For server deployments you might prefer using Docker to run aquadoggo.

docker run -p 2020:2020 -p 2022:2022 -e LOG_LEVEL=info p2panda/aquadoggo

Embed node

Run the node directly next to the frontend you're building for full peer-to-peer applications by using the aquadoggo Rust crate. Check out our Tauri example for writing a desktop app.

use aquadoggo::{Configuration, Node};
use p2panda_rs::identity::KeyPair;

let config = Configuration::default();
let key_pair = KeyPair::new();
let node = Node::start(key_pair, config).await;

FFI bindings

If you are not working with Rust you can create FFI bindings from the aquadoggo crate into your preferred programming language. Dealing with FFI bindings can be a bit cumbersome and we do not have much prepared for you (yet), but check out our Meli Android project as an example on how we dealt with FFI bindings for Dart / Flutter.

Query API

As an application developer the interface you are likely to use the most is the GraphQL query API. For whichever schema your node supports a custom query API is generated, you use this to fetch data into your app. Results from a collection query can be paginated, sorted and filtered.

Fetch one "mushroom" by its id, returning values for only the selected fields:

{
  mushroom: mushroom_0020c3accb0b0c8822ecc0309190e23de5f7f6c82f660ce08023a1d74e055a3d7c4d(
    id: "0020aaabb3edecb2e8b491b0c0cb6d7d175e4db0e9da6003b93de354feb9c52891d0"
  ) {
    fields {
      description
      edible
      latin
      title
    }
  }
}
Example query response
```json { "mushroom": { "description": "Its scientific name rhacodes comes from the Greek word rhakos, which means a piece of cloth. It does often have a soft, ragged fabric-like appearance.", "edible": true, "latin": "Chlorophyllum rhacodes", "title": "Shaggy parasol" } } ```

Fetch all "events" with ordering and filtering as well as selecting some meta fields. Here only events between the specified dates and with a title containing the string 'funtastic' will be returned, they will be arranged in ascending chronological order:

{
  events: all_events_0020aaabb3edecb2e8b491b0c0cb6d7d175e4db0e9da6003b93de354feb9c52891d0(
    first: 20
    orderBy: "happening_at"
    orderDirection: ASC
    filter: {
      title: { contains: "funtastic" }
      happening_at: { gte: 1677676480, lte: 1696162480 }
    }
  ) {
    totalCount
    documents {
      meta {
        owner
        documentId
        viewId
      }
      fields {
        title
        happening_at
      }
    }
  }
}
Example query response
```json { "events": { "totalCount": 2, "documents": [ { "meta": { "owner": "2f8e50c2ede6d936ecc3144187ff1c273808185cfbc5ff3d3748d1ff7353fc96", "documentId": "0020f3214a136fd6d0a649e14432409bb28a59a6caf723fa329129c404c92574cb41", "viewId": "00206e365e3a6a9b66dfe96ea4b3b3b7c61b250330a46b0c99134121603db5feef11" }, "fields": { "title": "Try funtasticize!!", "happening_at": 1680264880 } }, { "meta": { "owner": "2f8e50c2ede6d936ecc3144187ff1c273808185cfbc5ff3d3748d1ff7353fc96", "documentId": "002048a55d9265a16ba44b5f3be3e457238e02d3219ecca777d7b4edf28ba2f6d011", "viewId": "002048a55d9265a16ba44b5f3be3e457238e02d3219ecca777d7b4edf28ba2f6d011" }, "fields": { "title": "Is funtastic even a real word?", "happening_at": 1693484080 } } ] } } ```

Resources

What shouldn't I do with aquadoggo?

aquadoggo is built using the p2panda protocol which is in development and some planned features are still missing, the main ones being:

As well as these yet-to-be implemented features, there are also general networking concerns (exposing your IP address, sharing data with untrusted peers) that you should take into account when participating in any network, and particularily in peer-to-peer networks.

So although aquadoggo is already very useful in many cases, there are others where it won't be a good fit yet or we would actively warn against use. For now, any uses which would be handling especially sensitive data are not recommended, and any users who have special network security requirements need to take extra precautions. Reach out on our official chat if you have any questions.

License

GNU Affero General Public License v3.0 AGPL-3.0-or-later

Supported by



This project has received funding from the European Union’s Horizon 2020 research and innovation programme within the framework of the NGI-POINTER Project funded under grant agreement No 871528 and NGI-ASSURE No 957073