package coreapi import ( "context" "fmt" gopath "path" "github.com/ipfs/boxo/namesys/resolve" "github.com/ipfs/kubo/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" coreiface "github.com/ipfs/boxo/coreiface" path "github.com/ipfs/boxo/coreiface/path" ipfspath "github.com/ipfs/boxo/path" ipfspathresolver "github.com/ipfs/boxo/path/resolver" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" ) // ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the // resolved Node. func (api *CoreAPI) ResolveNode(ctx context.Context, p path.Path) (ipld.Node, error) { ctx, span := tracing.Span(ctx, "CoreAPI", "ResolveNode", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() rp, err := api.ResolvePath(ctx, p) if err != nil { return nil, err } node, err := api.dag.Get(ctx, rp.Cid()) if err != nil { return nil, err } return node, nil } // ResolvePath resolves the path `p` using Unixfs resolver, returns the // resolved path. func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Resolved, error) { ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String()))) defer span.End() if _, ok := p.(path.Resolved); ok { return p.(path.Resolved), nil } if err := p.IsValid(); err != nil { return nil, err } ipath := ipfspath.Path(p.String()) ipath, err := resolve.ResolveIPNS(ctx, api.namesys, ipath) if err == resolve.ErrNoNamesys { return nil, coreiface.ErrOffline } else if err != nil { return nil, err } if ipath.Segments()[0] != "ipfs" && ipath.Segments()[0] != "ipld" { return nil, fmt.Errorf("unsupported path namespace: %s", p.Namespace()) } var resolver ipfspathresolver.Resolver if ipath.Segments()[0] == "ipld" { resolver = api.ipldPathResolver } else { resolver = api.unixFSPathResolver } node, rest, err := resolver.ResolveToLastNode(ctx, ipath) if err != nil { return nil, err } root, err := cid.Parse(ipath.Segments()[1]) if err != nil { return nil, err } return path.NewResolvedPath(ipath, node, root, gopath.Join(rest...)), nil }