Mathe Eliel
Mathe Eliel

Reputation: 738

How to retrieve data from JS libp2p/kad-dht Distributed Hash Table?

I hope you are doing well. I created a Kademlia hash table to store content across nodes on the network. When using the get method, I am getting an AsyncIterable<QueryEvent>.

Can someone provide an example of how to extract data from the QueryEvent?

This is what I thought could work :

const extractDHTValue = async (res) => {
    let finalValue = null;

    for await (const event of res) {
        if (event.name === 'VALUE' && event.record) {
            // Extract the value from the record
            const value = uint8ArrayToString(event.record.value);
            console.log('DHT Record Value:', value);
            finalValue = value;
        }
    }

    if (finalValue === null) {
        console.log('No value found in the DHT query response.');
    }

    return finalValue;
};

I am unfortunately getting no value.

By the way, this is the way I am saving data on DHT :

import { createLibp2p } from 'libp2p';
import { tcp } from '@libp2p/tcp';
import { noise } from '@chainsafe/libp2p-noise';
import { stdinToStream, streamToConsole } from './stream.js';
import { yamux } from '@chainsafe/libp2p-yamux';
import { pipe } from 'it-pipe';
import { kadDHT } from '@libp2p/kad-dht';
import { identify, identifyPush } from '@libp2p/identify';
import { fromString as uint8fromString } from 'uint8arrays/from-string';

const start_server = async () => {
    const node = await createLibp2p({
        addresses: {
            listen: ["/ip4/0.0.0.0/tcp/10333"]
        },
        transports: [
            tcp()
        ],
        streamMuxers: [
            yamux()
        ],
        connectionEncrypters: [
            noise()
        ],
        contentRouters: [
            kadDHT()
        ],
        services: {
            identify: identify(),
            dht: kadDHT()
        }
    });

    // await node.start();
    node.addEventListener('peer:connect', (evt) => {
        console.log("New peer connected", evt);
        // const remotePeer = evt.details;
        // console.log('Connection established to:', remotePeer.toString());
    })

    await node.handle('/chat/1.0.0', async ({ stream }) => {
        console.log("New stream of chat protocol");
        stdinToStream(stream);
        streamToConsole(stream);

        // SAVING DUMB DATA HERE 
        await node.services.dht.put(uint8fromString('hello'), uint8fromString('world'));
        // CAN I READ THE DATA HERE TOO ?

        
    });

    node.getMultiaddrs().forEach((ma) => {
        console.log('Listening on:', ma.toString());
    });

    console.log('Node started!');
}

start_server();

Upvotes: 0

Views: 81

Answers (1)

Mathe Eliel
Mathe Eliel

Reputation: 738

I have solved this issue using it-last and the last() function.

import { toString as uint8toString } from 'uint8arrays';

// Some code

const extractDHTValue = async (res) => {
    
    let final_res = await last(res);
    let finalValue = final_res.value;
    // Will get a Uint8Array 
    // parse it back to string using to `toString` from `uint8arrays`
    
    return uint8toString(finalValue);
};

Upvotes: 0

Related Questions