[[tags: egg ipfs]]
== ipfs
[[toc:]]
=== Description
An egg to interface with the Kubo
[[https://docs.ipfs.io/reference/kubo/rpc|RPC API]]. Familiarity with it is
assumed in this document, and it will be useful to be able to use this library.
There are a ''few'' details that are unspecified or unclearly expressed in the
official documentation, that may lead to bugs or a wrong interface. If you
think you've found some error or if you've found something that can be improved
in this egg, please contact me. If, on the other hand, you've found some error
or something that can be improved with the official IPFS documentation, do
contact them (for example on Discourse or directly through an issue on GitHub).
In this latter case, and when relevant, I would appreciate if you could let me
know as well so I can be keep this egg up to date.
'''NOTE:''' This egg uses [[medea]] to read JSON that by default deserializes
object keys as symbols, which isn't great. There's the possibility to change
the JSON reader to use strings instead, but for now be warned: you shouldn't
use this library with an untrusted Kubo node, it may crash your program. In the
future the reader will be changed to read the keys as strings instead.
=== Author
siiky
=== Repository
[[https://git.sr.ht/~siiky/ipfs.scm]]
=== Requirements
The following eggs are required for using this egg:
* [[http-client]]
* [[intarweb]]
* [[medea]]
* [[openssl]] -- optional; mandatory if you want to use HTTPS
* [[srfi-1]]
* [[srfi-13]]
* [[srfi-189]]
* [[srfi-197]]
* [[uri-common]]
=== Version compatibility
ipfs.scm | Kubo |
0.0.1 | 0.11.0 |
0.0.2 | 0.12.0 |
0.0.3 | 0.13.0 |
0.0.4 | 0.14.0 ~ 0.15.0 |
0.0.5 ~ 0.0.6 | 0.16.0 |
0.0.7 ~ 0.0.8 | 0.17.0 |
0.0.9 | 0.18.0 ~ 0.18.1 |
0.0.10 | 0.19.0 ~ 0.19.1 |
0.0.11 | 0.20.0 |
0.0.12 | 0.21.0 |
0.0.13 | 0.22.0 ~ 0.25.0 |
0.0.14 | 0.26.0 ~ 0.27.0 |
0.0.15 | 0.28.0 |
0.0.16 | 0.29.0 |
=== API
The official docs define some clear terminology at the top of the page that
will be useful to know, even though sometimes they aren't themselves consistent
throughout that page (IMO):
; Arguments : (henceforth called '''API arguments''') are positional arguments (that correspond to positional arguments of the related CLI command) given through the {{arg}} key on the query string of the request.
; Flags : (henceforth called '''API flags''') are optional arguments (that correspond to flags/options of the related CLI command) given through their respective key on the query string of the request.
==== {{ipfs}} module
This is just a convenience module that reexports everything from the
{{ipfs.v0}} module described next.
==== {{ipfs.v0}} module
This module exports high-level procedures to communicate with the Kubo node on
the version {{v0}} of the API. For details, I would highly encourage you to
read the source code. Each endpoint is defined and exported using
{{export-rpc-call}} with a high-level and easy to read DSL to make defining the
whole of the API as easy and boilerplate-free as I can manage.
The exported procedures are named after the endpoint they're supposed to
represent. E.g., {{add}} for {{/api/v0/add}}, and {{bitswap/ledger}} for
{{/api/v0/bitswap/ledger}}.
API flags are given to the procedures as keyword arguments, with the name
defined in the API docs. E.g., the {{cid-version}} flag of {{add}} is given as
the {{#:cid-version}} keyword argument.
All procedures accept two common flags: {{#:offline}} and {{#:timeout}}. The
first is a boolean. When {{#t}}, the gateway will perform the operation in
offline mode, if possible. The {{#:timeout}} flag takes a string: a
human-readable duration of the sort accepted by the {{--timeout}} global option
of the ipfs CLI program.
API arguments are given to the procedures as keyword arguments as well, with a
declarative name. E.g., the one and only argument to {{bitswap/ledger}} is
called {{peer}} in this library, even though it is sent to the server as
{{arg}} in the query string. Since only API arguments may be required, and it's
not a PITA to specify them, procedures check for required arguments. The only
exceptions are the bodies of the endpoints that require one, such as {{add}}.
These must be given with the {{#:writer}} keyword argument, that is described
next.
All procedures have, on top of their arguments and flags, two extra keyword
arguments: {{#:reader}} and {{#:writer}}. These correspond, respectively, to
the {{reader-thunk}} and {{writer-thunk}} of {{with-input-from-request}} from
[[http-client]], and may be given on a per-RPC-call basis (for whatever reason;
e.g. performance maybe?). Unless noted otherwise (for some exceptions) all
procedures have a sane default value according to their corresponding endpoint
-- in general: {{reader/json}} for the reader and {{#f}} for the writer.
The body of {{add}} and others must be given as the {{#:writer}} keyword
argument, using for example the already defined writers {{writer/file}},
{{writer/directory}}, or {{writer/filesystem}}.
*scheme*
*host*
*port*
The scheme (HTTP/HTTPS), and hostname and port of the Kubo node you want to
interface with. The default values are {{'http}}, {{"localhost"}}, and {{5001}}
for {{*scheme*}}, {{*host*}}, and {{*port*}}, respectively. For details, see
the documentation for {{make-uri}} of [[uri-common]].
(reader/plain #!optional number (port (current-input-port)))
(reader/json #!optional (port (current-input-port)))
(reader/json+ #!optional (port (current-input-port)))
Convenience procedures to read the replies.
{{reader/plain}} is just a rename of {{read-string}} from {{(chicken io)}}.
{{reader/json}} is just a rename of {{read-json}} from [[medea]], except that
{{#:consume-trailing-whitespace}} is {{#f}}.
{{reader/json+}} is similar to {{reader/json}}, but it tries to read more than
one JSON message. This is used as the default reader for {{add}}, that returns
several JSON messages, one for each added file or directory. The deserialized
messages are returned in a list in the reverse order of appearance.
(writer/file path #!key name (headers '()))
(writer/directory path #!key name (headers '()))
(writer/filesystem path #!key test limit dotfiles follow-symlinks)
(writer/port port #!key name (headers '()))
(writer/string string name #!optional (headers '()))
(writer/file* path #!key name (headers '()))
(writer/directory* path #!key name (headers '()))
(writer/port* port #!key name (headers '()))
(writer/string* string name #!optional (headers '()))
Convenience procedures to use as the writer given to {{with-input-from-request}}.
{{name}} is the name of the file to be given to Kubo, that is, the name that
Kubo will use to save it. It is URI-encoded before sending.
{{headers}} is an alist of headers to use for an specific entry. See
{{with-input-from-request}}.
{{writer/file}} can be used to send a single file to the Kubo node. {{path}} is
the path to the file you want to send, and it must be accessible by the client
(this library), '''not''' the Kubo node. {{name}} defaults to the basename of
{{path}}. This allows special characters, such as
{{/}}, so you can send a path.
{{writer/directory}} can be used to send a single directory to the Kubo node.
The arguments of this function are similar to those of {{writer/file}}.
'''NOTE:''' This does '''not''' send other files or directories contained in
the specified directory, only an empty directory. For sending a file tree read
next.
{{writer/filesystem}} can be used to send a file tree to the Kubo node.
{{path}} specifies the root of the tree you want to send. For details on the
other parameters see the documentation for {{find-files}} of {{(chicken
file)}}.
{{writer/port}} can be used to send the contents of a port to the Kubo node. If
{{name}} is not given, {{with-input-from-request}} tries to use the port's own
name.
{{writer/string}} can be used to send a string as the contents of a file to the
Kubo node.
If none of these procedures quite fit your requirements, you can always build
the writer list to pass to {{with-input-from-request}} yourself.
{{writer/file*}}, {{writer/directory*}}, {{writer/port*}}, and
{{writer/string*}} may prove useful. They're similar to their non-asterisked
counterparts, but they return a single entry instead of an entry wrapped in a
list. See the [[#Examples|examples section]].
For more details, see {{writer/internal}} and {{writer/internal*}}.
==== {{ipfs.v0.lolevel}} module
This module exports the low-level procedures on which the high-level procedures
are built.
TODO: Complete documentation
(writer/internal* path #!optional name (headers '()))
(writer/internal path #!optional name (headers '()))
These are used internally by most {{writer/*}} procedures. They may be useful
to define your own writers when those already available don't suit your needs.
For more details, see the documentation for {{with-input-from-request}} and
{{call-with-input-request}} of the [[http-client]] egg. {{path}} corresponds to
{{file}}, {{name}} to {{filename}}, and {{headers}} to {{headers}}.
If {{name}} is provided it will be URI-encoded.
{{writer/internal*}} is to {{writer/internal}} what {{writer/file*}} is to
{{writer/file}}.
==== Missing Endpoints
You may find that some endpoints aren't implemented. There are two
possibilities: the endpoint is new and it hasn't been implemented yet; or, the
endpoint has been deprecated or calling it gives HTTP 404. For the former,
issues/PRs are very welcome! For the latter, if they're gone, they're gone. If
you really need them, you can search the Git log. E.g. {{git log -1 -p -S'(key
rotate)' -- ipfs.v0.scm}} will probably show you
[[https://git.sr.ht/~siiky/ipfs.scm/commit/3a3238049c6b484a1a8dc926e441cd454ddc7d0c|3a32380]].
=== Long-running Operations
Depending on your use case, some API calls may take a long time: minutes or
even hours. To prevent the connection to the node from being terminated
prematurely, you may want to adjust the TCP read timeout through the
{{tcp-read-timeout}} parameter of the {{(chicken tcp)}} module.
(import (chicken tcp))
(tcp-read-timeout #f)
=== Examples
(import ipfs)
(parameterize ((*port* 5006))
; Add `example-directory` and all files under it using CIDv1, but without
; pinning.
(print
(add #:writer (writer/filesystem "example-directory/")
#:cid-version 1
#:pin #f))
; Add a directory `dir/` and a file `my-file.txt` inside it, by manually
; constructing the writer list.
(let ((writer `(,(writer/directory* "~/some/directory/" #:name "dir/")
,(writer/file* "path/to/file.txt" #:name "dir/my-file.txt"))))
(print (add #:writer writer #:cid-version 1 #:pin #f #:only-hash #t)))
; Get a list of all the peers the node is connected to.
(print (swarm/peers)))
=== License
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
=== Version History
==== 0.0.1 (2022/03/22)
* Initial release.
==== 0.0.2 (2022/06/14)
* Gather endpoint definitions in a single {{include}}able file -- makes it
easier to export to other languages.
* Add {{export-to-lua.scm}}.
* Change query-string separator to {{&}}.
==== 0.0.3 (2022/06/21)
* Update exported endpoints to match the latest IPFS v0.13.0
([[https://github.com/ipfs/go-ipfs/releases/tag/v0.13.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/26b315c3b2073243030c238278d8df65643208e6/docs/reference/http/api.md|API docs]]).
* Remove {{progress}} flags -- I believe they're ignored for the HTTP API.
==== 0.0.4 (2022/07/23)
* Update exported endpoints to match the latest Kubo v0.14.0
([[https://github.com/ipfs/kubo/releases/tag/v0.14.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/ca6603d06b143b483251fd8e43b7bbdcf89d8756/docs/reference/kubo/rpc.md|API docs]]);
* Rename {{dht/*}} to {{routing/*}};
* Change the default reader of {{refs}} and {{refs/local}} to {{reader/json+}}, thanks to teiresias;
* Add note about TCP timeouts to the docs, thanks to teiresias.
==== 0.0.5 (2022/10/08)
* Update exported endpoints to match the latest Kubo v0.16.0
([[https://github.com/ipfs/kubo/releases/tag/v0.16.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/e39d1ba967a9bffb06df3e377917acb5bf1c8cb6/docs/reference/kubo/rpc.md|API docs]]);
* Add {{to-files}} flag to {{add}}.
==== 0.0.6 (2022/10/09)
* Add {{#:offline}} and {{#:timeout}} flags, thanks to teiresias.
==== 0.0.7 (2022/11/26)
* Update exported endpoints to match the latest Kubo v0.17.0
([[https://github.com/ipfs/kubo/releases/tag/v0.17.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/8d1aae1637a2299db22153d3060b6cca4f5ffb37/docs/reference/kubo/rpc.md|API docs]]);
* Add {{repo/ls}};
* Add {{reset}} flag to {{swarm/limit}};
* Add {{min-used-limit-perc}} flag to {{swarm/stats}};
* Add {{writer/port}}, {{writer/string}}, {{writer/port*}}, and {{writer/string*}}, as suggested by teiresias.
==== 0.0.8 (2022/11/27)
* Export {{writer/*}} procedures from {{ipfs.v0}} module.
==== 0.0.9 (2023/01/29)
* Update exported endpoints to match the latest Kubo v0.18.0
([[https://github.com/ipfs/kubo/releases/tag/v0.18.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/82da9516dcd665e84e890678b7b8ed61cba1bc05/docs/reference/kubo/rpc.md|API docs]]);
* Modify {{writer/filesystem}} to not send directories.
==== 0.0.10 (2023/03/25)
* Update exported endpoints to match the latest Kubo v0.19.0
([[https://github.com/ipfs/kubo/releases/tag/v0.19.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/60c0c0b36768d49d8e9fd3dc8d9b99d74e5ca107/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.11 (2023/05/15)
* Update exported endpoints to match the latest Kubo v0.20.0
([[https://github.com/ipfs/kubo/releases/tag/v0.20.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/9661bdfe4c1d972216babec98c2b94cc28603954/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.12 (2023/07/03)
* Update exported endpoints to match the latest Kubo v0.21.0
([[https://github.com/ipfs/kubo/releases/tag/v0.21.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/8b4134a2744a6e53592fea21823c8c1d2cba4800/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.13 (2023/08/12)
* Update exported endpoints to match the latest Kubo v0.22.0
([[https://github.com/ipfs/kubo/releases/tag/v0.22.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/ed72508085fe34f0882d2e41b9479a8344b6093e/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.14 (2024/01/30)
* Update exported endpoints to match the latest Kubo v0.26.0
([[https://github.com/ipfs/kubo/releases/tag/v0.26.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/0427b6eaf6f0a8a0de1d4abaf7008d443d5f7a7e/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.15 (2024/04/16)
* Update exported endpoints to match the latest Kubo v0.28.0
([[https://github.com/ipfs/kubo/releases/tag/v0.26.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/827ab23d533f2bf18656ee20a89cdc80e858ed0a/docs/reference/kubo/rpc.md|API docs]]).
==== 0.0.16 (2024/07/14)
* Update exported endpoints to match the latest Kubo v0.29.0
([[https://github.com/ipfs/kubo/releases/tag/v0.29.0|release notes]];
[[https://github.com/ipfs/ipfs-docs/blob/65cad2052d9d1c53e94d70c51108935411816dba/docs/reference/kubo/rpc.md|API docs]]).