Packages

An elixir client library for the IPFS API

Current section

Files

Jump to
elixir_ipfs_api lib ipfs-api.ex
Raw

lib/ipfs-api.ex

defmodule IpfsApi do
@moduledoc """
The module is a client to call into IPFS REST endpoint.
"""
@type request_ret :: {:ok, Dict.t} | {:error, String.t}
#########################
#####Basic Commands######
#########################
@spec add(IpfsConnection.t, binary) :: request_ret
def add(_connection, <<>>) do
{:error, "No content provided"}
end
@doc ~S"""
Add an object to ipfs
## Examples
IpfsApi.add(%IpfsConnection{}, "Hello World")
"""
@spec add(IpfsConnection.t, binary) :: request_ret
def add(connection, content) do
connection
|> create_url("/add")
|> request_send_file(content)
end
@doc ~S"""
Get an ipfs object
## Examples
IpfsApi.get(%IpfsConnection{}, "QmUXTtySmd7LD4p6RG6rZW6RuUuPZXTtNMmRQ6DSQo3aMw")
"""
@spec get(IpfsConnection.t, String.t) :: {:ok, binary} | {:error, String.t}
def get(connection, multihash) do
connection
|> create_url("/get/#{multihash}")
|> request_get_file
end
@doc ~S"""
Show ipfs object data
"""
@spec cat(IpfsConnection.t, String.t) :: request_ret
def cat(connection, multihash) do
connection
|> request(:get, "/cat", [multihash])
end
@doc ~S"""
List links from an object
"""
@spec ls(IpfsConnection.t, String.t) :: request_ret
def ls(connection, multihash) do
connection
|> request(:get, "/ls", [multihash])
end
@doc ~S"""
List hashes of links from an object
"""
@spec refs(IpfsConnection.t, String.t) :: request_ret
def refs(connection, multihash) do
connection
|> request(:get, "/refs", [multihash])
end
#########################
#Data Structure Commands#
#########################
@doc ~S"""
Print information of a raw IPFS block
"""
@spec block_stat(IpfsConnection.t, String.t) :: request_ret
def block_stat(connection, multihash) do
connection
|> request(:get, "/block/stat", [multihash])
end
@doc ~S"""
Get a raw IPFS block
"""
@spec block_get(IpfsConnection.t, String.t) :: request_ret
def block_get(connection, multihash) do
connection
|> request(:get, "/block/get", [multihash])
end
@doc ~S"""
Stores input as an IPFS block
"""
@spec block_put(IpfsConnection.t, binary) :: request_ret
def block_put(connection, content) do
connection
|> create_url("/block/put")
|> request_send_file(content)
end
@doc ~S"""
The raw bytes in an IPFS object
"""
@spec object_data(IpfsConnection.t, String.t) :: request_ret
def object_data(connection, multihash) do
connection
|> request(:get, "/object/data", [multihash])
end
@doc ~S"""
The links pointed to by the specified object
"""
@spec object_links(IpfsConnection.t, String.t) :: request_ret
def object_links(connection, multihash) do
connection
|> request(:get, "/object/links", [multihash])
end
@doc ~S"""
Get and serialize the DAG node name by `multihash`
"""
@spec object_get(IpfsConnection.t, String.t) :: request_ret
def object_get(connection, multihash) do
connection
|> request(:get, "/object/get", [multihash])
end
@doc ~S"""
Stores `content` as a DAG object
"""
@spec object_put(IpfsConnection.t, binary) :: request_ret
def object_put(connection, content) do
connection
|> create_url("/block/put")
|> request_send_file(content)
end
@doc ~S"""
Get stats for the DAG node name by `key`
"""
@spec object_stat(IpfsConnection.t, String.t) :: request_ret
def object_stat(connection, key) do
connection
|> request(:get, "/object/stat", [key])
end
@doc ~S"""
Create a new merkledag object base on an existing one
"""
@spec object_patch(IpfsConnection.t, String.t) :: request_ret
def object_patch(connection, key) do
connection
|> request(:get, "/object/patch", [key])
end
@doc ~S"""
List directory content for `path`
"""
@spec file_ls(IpfsConnection.t, String.t) :: request_ret
def file_ls(connection, path) do
connection
|> request(:get, "/file/ls", [path])
end
#########################
####Advanced Commands####
#########################
@doc ~S"""
Resolve the value of the `name`
TODO: Add ability to resolve recursively
"""
@spec resolve(IpfsConnection.t, String.t) :: request_ret
def resolve(connection, name) do
connection
|> request(:get, "/resolve", [name])
end
@doc ~S"""
Publish the `ipfs_path` to your identity name
"""
@spec name_publish(IpfsConnection.t, String.t) :: request_ret
def name_publish(connection, ipfs_path) do
connection
|> request(:get, "/name/publish", [ipfs_path])
end
@doc ~S"""
Resolve the value of `name`
"""
@spec name_resolve(IpfsConnection.t, String.t) :: request_ret
def name_resolve(connection, name \\ "") do
connection
|> request(:get, "/name/resolve", [name])
end
@doc ~S"""
Resolve the DNS link
TODO: Add ability to resolve recursively
"""
@spec dns(IpfsConnection.t, String.t) :: request_ret
def dns(connection, domain_name) do
connection
|> request(:get, "/dns", [domain_name])
end
@doc ~S"""
Pins objects to local storage
"""
@spec pin_add(IpfsConnection.t, String.t) :: request_ret
def pin_add(connection, ipfs_path) do
connection
|> request(:get, "/pin/add", [ipfs_path])
end
@doc ~S"""
Remove the pinned object from local storage
TODO: Add ability to resolve recursively
"""
@spec pin_rm(IpfsConnection.t, String.t) :: request_ret
def pin_rm(connection, ipfs_path) do
connection
|> request(:get, "/pin/rm", [ipfs_path])
end
@doc ~S"""
List objects pinned to local storage
"""
@spec pin_ls(IpfsConnection.t) :: request_ret
def pin_ls(connection) do
connection
|> request(:get, "/pin/ls", [])
end
@doc ~S"""
Perform a grabage collection sweep on the repo
"""
@spec repo_gc(IpfsConnection.t) :: request_ret
def repo_gc(connection) do
connection
|> request(:get, "/repo/gc", [])
end
#########################
####Network Commands#####
#########################
@doc ~S"""
Gets the information about the specified `peer_id`
"""
@spec id(IpfsConnection.t, String.t) :: request_ret
def id(connection, peer_id \\ "") do
connection
|> request(:get, "/id", [peer_id])
end
@doc ~S"""
Gets the list of bootstrap peers
"""
@spec bootstrap(IpfsConnection.t) :: request_ret
def bootstrap(connection) do
connection
|> request(:get, "/bootstrap", [])
end
@doc ~S"""
Add peers to the bootstrap list
"""
@spec bootstrap_add(IpfsConnection.t, String.t) :: request_ret
def bootstrap_add(connection, peer) do
connection
|> request(:get, "/bootstrap/add", [peer])
end
@doc ~S"""
Remoes peers from the bootstrap list
"""
@spec bootstrap_rm(IpfsConnection.t, String.t) :: request_ret
def bootstrap_rm(connection, peer) do
connection
|> request(:get, "/bootstrap/rm", [peer])
end
@doc ~S"""
List peers with open connections
"""
@spec swarm_peers(IpfsConnection.t) :: request_ret
def swarm_peers(connection) do
connection
|> request(:get, "/swarm/peers", [])
end
@doc ~S"""
List known addresses
"""
@spec swarm_addr(IpfsConnection.t) :: request_ret
def swarm_addr(connection) do
connection
|> request(:get, "/swarm/addrs", [])
end
@doc ~S"""
Open connection to given `address`
"""
@spec swarm_connect(IpfsConnection.t, String.t) :: request_ret
def swarm_connect(connection, address) do
connection
|> request(:get, "/swarm/connect", [address])
end
@doc ~S"""
Close connection to give address
"""
@spec swarm_disconnect(IpfsConnection.t, String.t) :: request_ret
def swarm_disconnect(connection, address) do
connection
|> request(:get, "/swarm/disconnect", [address])
end
@doc ~S"""
Add an address filter
"""
@spec swarm_filters_add(IpfsConnection.t, String.t) :: request_ret
def swarm_filters_add(connection, address) do
connection
|> request(:get, "/swarm/filters/add", [address])
end
@doc ~S"""
Remove an address filter
"""
@spec swarm_filters_rm(IpfsConnection.t, String.t) :: request_ret
def swarm_filters_rm(connection, address) do
connection
|> request(:get, "/swarm/filters/rm", [address])
end
@doc ~S"""
Run a FindClosesPeers query through the DHT
"""
@spec dht_query(IpfsConnection.t, String.t) :: request_ret
def dht_query(connection, peer_id) do
connection
|> request(:get, "/dht/query", [peer_id])
end
@doc ~S"""
Run a FundProviders quest through the DHT
"""
@spec dht_findprovs(IpfsConnection.t, String.t) :: request_ret
def dht_findprovs(connection, key) do
connection
|> request(:get, "/dht/findprovs", [key])
end
@doc ~S"""
Run a FindPeer query through the DHT
"""
@spec dht_findpeer(IpfsConnection.t, String.t) :: request_ret
def dht_findpeer(connection, peer_id) do
connection
|> request(:get, "/dht/findpeer", [peer_id])
end
@doc ~S"""
Run a GetValue query through the DHT
"""
@spec dht_get(IpfsConnection.t, String.t) :: request_ret
def dht_get(connection, key) do
connection
|> request(:get, "/dht/get", [key])
end
@doc ~S"""
Run a PutValue query through the DHT
"""
@spec dht_put(IpfsConnection.t, String.t, String.t) :: request_ret
def dht_put(connection, key, value) do
connection
|> request(:get, "/dht/put", [key, value])
end
@doc ~S"""
Send echo request packets to IPFS hosts
TODO: Add ability to give number of count
"""
@spec ping(IpfsConnection.t, String.t) :: request_ret
def ping(connection, peer_id) do
connection
|> request(:get, "/ping", [peer_id])
end
#########################
######Tool Commands######
#########################
# def config() do
@doc ~S"""
Gets the content of the config file
"""
@spec config_show(IpfsConnection.t) :: request_ret
def config_show(connection) do
connection
|> request(:get, "/config/show", [])
end
# def config_replace() do
@doc ~S"""
Gets the IPFS version
"""
@spec version(IpfsConnection.t) :: request_ret
def version(connection) do
connection
|> request(:get, "/version", [])
end
#########################
####Helper Functions#####
#########################
defp create_url(connection, path) do
"#{connection.host}:#{connection.port}/#{connection.base}#{path}"
end
defp request_send_file(url, content) do
url
|> (fn(url) ->
boundary = "a831rwxi1a3gzaorw1w2z49dlsor"
HTTPoison.request(:post, url, create_add_body(content, boundary), [
{"Content-Type", "multipart/form-data; boundary=#{boundary}"}])
end).()
|> process_response
end
defp request_get_file(url) do
url
|> HTTPoison.get
|> process_response(&(&1))
end
defp request(connection, req_type, path, args) do
request_internal(connection, req_type, create_url(connection, path), args)
end
defp request_internal(_connection, :post, url, %{} = args) do
url
|> HTTPoison.post(Poison.encode(args))
|> process_response
end
defp request_internal(_connection, :get, url, []) do
HTTPoison.get(url)
|> process_response
end
defp request_internal(connection, :get, url, [h | t]) do
request(connection, :get, "#{url}/#{h}", t)
end
defp process_response(response) do
process_response(response, &Poison.decode/1)
end
defp process_response({:ok, %HTTPoison.Response{status_code: 200, body: body}}, deserializationFunc) do
deserializationFunc.(body)
end
defp process_response({:ok, %HTTPoison.Response{status_code: code, body: body}}, _deserializationFunc) do
{:error, "Error status code: #{code}, #{body}"}
end
defp process_response({:error, %HTTPoison.Error{reason: reason}}, _deserializationFunc) do
{:error, reason}
end
defp create_add_body(content, boundary) do
"--#{boundary}\r\nContent-Type: application/octet-stream\r\nContent-Disposition: file; \r\n\r\n#{content} #{boundary}"
end
end