A minimal Java implementation of IPFS
Nabu is the ancient Mesopotamian patron god of literacy, the rational arts, scribes, and wisdom.
This is a WIP. You can follow our progress updates here.
Currently implemented properties:
- TCP transport
- Noise encryption and authentication
- TLS security provider (with early muxer negotiation using ALPN)
- RSA and Ed25519 peer IDs
- yamux and mplex muxers
- Kademlia DHT for peer routing, IPNS publishing and fallback content discovery
- Bitswap 1.2.0 + auth extension as used in Peergos
- p2p http proxy
- dnsaddr multiaddr resolution during bootstrap
- autonat
- uPnP port forwarding
- nat-pmp port forwarding
- file and S3 based blockstore
- persistent datastores (IPNS record store) using H2 DB
- persistent identities and config
- basic HTTP API (block.{get, put, rm, has, stat}, id, getRefs, bloomAdd) compatible with matching kubo api calls
- bloom/infini filtered blockstore
- connect bitswap to kademlia for discovery, with a faster version with supplied peerids
- configurable cid publishing function
- mDNS peer discovery
- Android compatibility
- example serverless chat app using p2p http proxy for Android
- interop tests with other implementations - https://github.com/libp2p/test-plans/
In the future we will add:
- circuit-relay
- dcutr (direct connection upgrade through relay)
- AutoRelay
- example iOS chat app
- QUIC transport (and encryption and multiplexing)
You can use this as a standalone application for storing and retrieving blocks. Or you can embed it in your application.
Package managers are supported through JitPack which supports Maven, Gradle, SBT, etc.
for Maven, add the following sections to your pom.xml (replacing $LATEST_VERSION):
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.github.peergos</groupId>
<artifactId>nabu</artifactId>
<version>$LATEST_VERSION</version>
</dependency>
</dependencies>
Build using Maven
mvn package -Dmaven.test.skip=true
List<MultiAddress> swarmAddresses = List.of(new MultiAddress("/ip6/::/tcp/4001"));
List<MultiAddress> bootstrapAddresses = List.of(new MultiAddress("/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"));
BlockRequestAuthoriser authoriser = (cid, peerid, auth) -> CompletableFuture.completedFuture(true);
HostBuilder builder = new HostBuilder().generateIdentity();
PrivKey privKey = builder.getPrivateKey();
PeerId peerId = builder.getPeerId();
IdentitySection identity = new IdentitySection(privKey.bytes(), peerId);
boolean provideBlocks = true;
SocketAddress httpTarget = new InetSocketAddress("localhost", 10000);
Optional<HttpProtocol.HttpRequestProcessor> httpProxyTarget =
Optional.of((s, req, h) -> HttpProtocol.proxyRequest(req, httpTarget, h));
EmbeddedIpfs ipfs = EmbeddedIpfs.build(new RamRecordStore(),
new FileBlockstore(Path.of("/home/alice/ipfs")),
provideBlocks,
swarmAddresses,
bootstrapAddresses,
identity,
authoriser,
httpProxyTarget
);
ipfs.start();
List<Want> wants = List.of(new Want(Cid.decode("zdpuAwfJrGYtiGFDcSV3rDpaUrqCtQZRxMjdC6Eq9PNqLqTGg")));
Set<PeerId> retrieveFrom = Set.of(PeerId.fromBase58("QmVdFZgHnEgcedCS2G2ZNiEN59LuVrnRm7z3yXtEBv2XiF"));
boolean addToLocal = true;
List<HashedBlock> blocks = ipfs.getBlocks(wants, retrieveFrom, addToLocal);
byte[] data = blocks.get(0).block;
If you want a working example app you can fork, have a look at our chat example. This is a simple CLI app where two users exchange peerid (out of band) and then connect and send messages via p2p http requests, which are printed to the console.
By default, Nabu will construct a File based blockstore
If you are configuring a brand new Nabu instance without any data, you can enable S3 by passing in a command line parameter:
-s3.datastore "{\"region\": \"us-east-1\", \"bucket\": \"$bucketname\", \"rootDirectory\": \"$bucketsubdirectory\", \"regionEndpoint\": \"us-east-1.linodeobjects.com\", \"accessKey\": \"1\", \"secretKey\": \"2\"}
Note: accessKey and secretKey are optional. They can be set via env vars AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY or read from ~/.aws/credentials