import { multiaddr } from '@multiformats/multiaddr';
import { create as createKuboClient, IPFSHTTPClient } from 'kubo-rpc-client';
import { CYBER_GATEWAY_URL } from '../../config';
import {
  AbortOptions,
  CatOptions,
  InitOptions,
  IpfsFileStats,
  IpfsNode,
  IpfsNodePrperties,
  IpfsNodeType,
} from '../../types';
import { stringToCid, stringToIpfsPath } from '../../utils/cid';

class KuboNode implements IpfsNode {
  readonly nodeType: IpfsNodeType = 'external';

  private node?: IPFSHTTPClient;

  private _config: IpfsNodePrperties = {};

  get config() {
    return this._config;
  }

  private _isStarted = false;

  get isStarted() {
    return this._isStarted;
  }

  private async initConfig(userGateway?: string) {
    try {
      const response = await this.node!.config.get('Addresses.Gateway');
      if (response) {
        const address = multiaddr(response as string).nodeAddress();
        return { gatewayUrl: `http://${address.address}:${address.port}` };
      }
    } catch (err) {
      console.warn('๐Ÿ”‹ ipfs config.get failed (using gateway fallback):', (err as Error)?.message);
    }
    return { gatewayUrl: userGateway || CYBER_GATEWAY_URL };
  }

  async init(options?: InitOptions) {
    console.log('๐Ÿ”‹ ipfs KuboNode init', options);

    this.node = createKuboClient(options);
    console.log('๐Ÿ”‹ ipfs KuboNode initialized', this.node);

    console.log('๐Ÿ”‹ ipfs config init');
    this._config = await this.initConfig(options?.userGateway);
    console.log('๐Ÿ”‹ ipfs config initialized', this._config);

    if (typeof window !== 'undefined') {
      window.node = this.node;
      window.toCid = stringToCid;
    }

    // const kuboAddresses = (await this.node.swarm.localAddrs()).map((a) =>
    //   a.toString()
    // );
    // console.log('๐Ÿ”‹ ipfs - Kubo addrs', kuboAddresses);

    this._isStarted = true;
  }

  async stat(cid: string, options: AbortOptions = {}): Promise<IpfsFileStats> {
    return this.node!.files.stat(stringToIpfsPath(cid), {
      ...options,
      withLocal: true,
      size: true,
    }).then((result) => {
      const { type, size, sizeLocal, local, blocks } = result;
      return {
        type,
        size: size || -1,
        sizeLocal: sizeLocal || -1,
        blocks,
      };
    });
  }

  cat(cid: string, options: CatOptions = {}) {
    return this.node!.cat(stringToCid(cid), options);
  }

  async add(content: File | string, options: AbortOptions = {}) {
    return (await this.node!.add(content, options)).cid.toString();
  }

  async pin(cid: string, options: AbortOptions = {}) {
    return (await this.node!.pin.add(stringToCid(cid), options)).toString();
  }

  async getPeers() {
    return (await this.node!.swarm.peers()).map((c) => c.peer.toString());
  }

  async stop() { }

  async start() { }

  async connectPeer(address: string) {
    const addr = multiaddr(address);
    await this.node!.bootstrap.add(addr);

    await this.node!.swarm.connect(addr);
    return true;
  }

  ls() {
    return this.node!.pin.ls();
  }

  async info() {
    const { repoSize } = await this.node!.stats.repo();

    const responseId = await this.node!.id();
    const { agentVersion, id } = responseId;
    return { id: id.toString(), agentVersion, repoSize };
  }
}

// eslint-disable-next-line import/no-unused-modules
export default KuboNode;

Synonyms

pussy-ts/src/services/ipfs/node/impl/kubo.ts

Neighbours