ipfs

package module
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 33 Imported by: 1

README

ipfs-tools

Tests Go Reference

Go library for fetching data from IPFS. It provides two ways to resolve content:

  • Gateway pool — fetch documents over HTTP from a list of public/private IPFS gateways with per-gateway rate limiting;
  • Embedded node — run an in-process Kubo IPFS node tuned for low resource usage and fetch content directly from the network.

Plus a set of helpers for parsing and validating ipfs:// links.

Installation

go get github.com/dipdup-io/ipfs-tools

Usage

Gateway pool

Pool requests content from HTTP gateways. Each gateway gets its own rate limiter (10 requests per second). Response size is capped by limit (bytes).

package main

import (
	"context"
	"fmt"

	ipfs "github.com/dipdup-io/ipfs-tools"
)

func main() {
	pool, err := ipfs.NewPool([]string{
		"https://ipfs.io",
		"https://cloudflare-ipfs.com",
	}, 1024*1024) // 1 MB response limit
	if err != nil {
		panic(err)
	}

	// tries gateways in random order until one responds
	data, err := pool.Get(context.Background(), "ipfs://QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU")
	if err != nil {
		panic(err)
	}

	fmt.Printf("received %d bytes from %s\n", len(data.Raw), data.Node)
}

Other ways to query the pool:

// single request to one randomly chosen gateway
data, err := pool.GetFromRandomGateway(ctx, link)

// request to a specific gateway
data, err := pool.GetFromNode(ctx, link, "https://ipfs.io")

The pool implements the IPool interface; a gomock mock (MockIPool) is shipped with the package for testing.

Embedded IPFS node

Node spawns an in-process Kubo node. The repo config is tuned to minimize resource usage: no relay/QUIC transports, delegated routing, providing and Bitswap server disabled, connection manager capped at 20–50 peers, 2 GB storage with hourly GC.

node, err := ipfs.NewNode(ctx,
	"/path/to/ipfs-repo",       // repo directory (created if missing)
	1024*1024,                  // read limit in bytes
	[]string{},                 // swarm address blacklist (addr filters)
	[]ipfs.Provider{            // peers to keep persistent connections with
		{ID: "12D3KooW...", Address: "/dns4/example.com/tcp/4001"},
	},
)
if err != nil {
	panic(err)
}

if err := node.Start(ctx); err != nil { // connects to peers, starts periodic GC
	panic(err)
}
defer node.Close()

data, err := node.Get(ctx, "/ipfs/QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU")
Helpers
// extract and validate a CID from a link
hash, err := ipfs.Hash("ipfs://QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU")

// find all ipfs:// links (CIDv0 and CIDv1) in raw bytes
links := ipfs.FindAllLinks(data)

// check whether a string is a valid ipfs:// link
ok := ipfs.Is("ipfs://QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU")

// build a gateway URL from gateway address and hash
url := ipfs.Link("https://ipfs.io", hash) // https://ipfs.io/ipfs/<hash>

// strip the ipfs:// prefix
path := ipfs.Path("ipfs://<hash>") // <hash>

Development

make test   # go test ./...
make lint   # golangci-lint run

Mocks are generated with mockgen:

go generate ./...

License

MIT — see LICENSE.

Documentation

Overview

Package ipfs is a generated GoMock package.

Index

Constants

View Source
const (
	IpfsLinkPrefix = "ipfs://"
)

prefix

Variables

View Source
var (
	ErrInvalidURI           = errors.New("invalid URI")
	ErrEmptyIPFSGatewayList = errors.New("empty IPFS gateway list")
	ErrHTTPRequest          = errors.New("HTTP request error")
	ErrJSONDecoding         = errors.New("JSON decoding error")
	ErrNoIPFSResponse       = errors.New("can't load document from IPFS")
	ErrInvalidCID           = errors.New("invalid CID")
)

Errors

Functions

func FindAllLinks(data []byte) []string

FindAllLinks -

func Hash

func Hash(link string) (string, error)

Hash - separate IPFS hash from link

func Is

func Is(link string) bool

Is -

func Link(gateway, hash string) string

Link - get gateway link

func Path

func Path(link string) string

Path - get path without protocol

func ShuffleGateways

func ShuffleGateways(gateways []string) []string

ShuffleGateways - shuffle gateways for different request order for different files

Types

type Data

type Data struct {
	Raw          []byte
	Node         string
	ResponseTime int64
}

Data -

type IPool added in v0.0.5

type IPool interface {
	Get(ctx context.Context, link string) (Data, error)
	GetFromRandomGateway(ctx context.Context, link string) (Data, error)
	GetFromNode(ctx context.Context, link, node string) (Data, error)
}

type MockIPool added in v0.0.5

type MockIPool struct {
	// contains filtered or unexported fields
}

MockIPool is a mock of IPool interface.

func NewMockIPool added in v0.0.5

func NewMockIPool(ctrl *gomock.Controller) *MockIPool

NewMockIPool creates a new mock instance.

func (*MockIPool) EXPECT added in v0.0.5

func (m *MockIPool) EXPECT() *MockIPoolMockRecorder

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockIPool) Get added in v0.0.5

func (m *MockIPool) Get(ctx context.Context, link string) (Data, error)

Get mocks base method.

func (*MockIPool) GetFromNode added in v0.0.5

func (m *MockIPool) GetFromNode(ctx context.Context, link, node string) (Data, error)

GetFromNode mocks base method.

func (*MockIPool) GetFromRandomGateway added in v0.0.5

func (m *MockIPool) GetFromRandomGateway(ctx context.Context, link string) (Data, error)

GetFromRandomGateway mocks base method.

type MockIPoolGetCall added in v0.0.5

type MockIPoolGetCall struct {
	*gomock.Call
}

MockIPoolGetCall wrap *gomock.Call

func (*MockIPoolGetCall) Do added in v0.0.5

Do rewrite *gomock.Call.Do

func (*MockIPoolGetCall) DoAndReturn added in v0.0.5

func (c *MockIPoolGetCall) DoAndReturn(f func(context.Context, string) (Data, error)) *MockIPoolGetCall

DoAndReturn rewrite *gomock.Call.DoAndReturn

func (*MockIPoolGetCall) Return added in v0.0.5

func (c *MockIPoolGetCall) Return(arg0 Data, arg1 error) *MockIPoolGetCall

Return rewrite *gomock.Call.Return

type MockIPoolGetFromNodeCall added in v0.0.5

type MockIPoolGetFromNodeCall struct {
	*gomock.Call
}

MockIPoolGetFromNodeCall wrap *gomock.Call

func (*MockIPoolGetFromNodeCall) Do added in v0.0.5

Do rewrite *gomock.Call.Do

func (*MockIPoolGetFromNodeCall) DoAndReturn added in v0.0.5

DoAndReturn rewrite *gomock.Call.DoAndReturn

func (*MockIPoolGetFromNodeCall) Return added in v0.0.5

Return rewrite *gomock.Call.Return

type MockIPoolGetFromRandomGatewayCall added in v0.0.5

type MockIPoolGetFromRandomGatewayCall struct {
	*gomock.Call
}

MockIPoolGetFromRandomGatewayCall wrap *gomock.Call

func (*MockIPoolGetFromRandomGatewayCall) Do added in v0.0.5

Do rewrite *gomock.Call.Do

func (*MockIPoolGetFromRandomGatewayCall) DoAndReturn added in v0.0.5

DoAndReturn rewrite *gomock.Call.DoAndReturn

func (*MockIPoolGetFromRandomGatewayCall) Return added in v0.0.5

Return rewrite *gomock.Call.Return

type MockIPoolMockRecorder added in v0.0.5

type MockIPoolMockRecorder struct {
	// contains filtered or unexported fields
}

MockIPoolMockRecorder is the mock recorder for MockIPool.

func (*MockIPoolMockRecorder) Get added in v0.0.5

func (mr *MockIPoolMockRecorder) Get(ctx, link any) *MockIPoolGetCall

Get indicates an expected call of Get.

func (*MockIPoolMockRecorder) GetFromNode added in v0.0.5

func (mr *MockIPoolMockRecorder) GetFromNode(ctx, link, node any) *MockIPoolGetFromNodeCall

GetFromNode indicates an expected call of GetFromNode.

func (*MockIPoolMockRecorder) GetFromRandomGateway added in v0.0.5

func (mr *MockIPoolMockRecorder) GetFromRandomGateway(ctx, link any) *MockIPoolGetFromRandomGatewayCall

GetFromRandomGateway indicates an expected call of GetFromRandomGateway.

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node -

func NewNode

func NewNode(ctx context.Context, dir string, limit int64, blacklist []string, providers []Provider) (*Node, error)

NewNode -

func (*Node) Close

func (n *Node) Close() error

Close -

func (*Node) Get

func (n *Node) Get(ctx context.Context, cid string) (Data, error)

Get -

func (*Node) Start

func (n *Node) Start(ctx context.Context) error

Start -

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool -

func NewPool

func NewPool(gateways []string, limit int64) (*Pool, error)

NewPool -

func (*Pool) Get

func (pool *Pool) Get(ctx context.Context, link string) (Data, error)

Get - returns result if one of node returns it

func (*Pool) GetFromNode

func (pool *Pool) GetFromNode(ctx context.Context, link, node string) (Data, error)

GetFromNode - returns result if `node` returns it

func (*Pool) GetFromRandomGateway

func (pool *Pool) GetFromRandomGateway(ctx context.Context, link string) (Data, error)

GetFromRandomGateway - returns result if random node returns it

type Provider

type Provider struct {
	ID      string `validate:"required" yaml:"id"`
	Address string `validate:"required" yaml:"addr"`
}

Provider -

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
⌂ 换网址