---
# System prepended metadata

title: IPFS Client API

---



# IPFS Client API

Goals:
- **Any client API should solve the issues from this [doc](https://hackmd.io/rxFtUuTdRTO4-nyAxPHNqQ).**
- Be generic enough to allow integration in host applications that have different internals designs.
- Hide IPFS details from hosts.
- Support all major OSes.
- Be usable as a C compatible ffi.

WebIdl-like definition:

```idl
// Implemented by objects receiving data.
interface DataSink {
    void start();
    void stop();
    void error(error: String|SomeBetterErrorType)
    void data(buffer: Array<u8>);
}

// Makes it possible to cancel an ongoing request.
// Needed when racing origin servers to cancel the
// requests that won't be used.
interface Cancelable {
    void cancel()
}

// Implemented by some object that can use the host internal capabilities,
// or use fallback implementations provided by the IPFS client
// library itself.
interface HostDelegate {
    Cancelable fetchHttp(url: Url, sink: DataSink)
    Promise<String> dnsRecord(name: String, record: String)
    Promise<Array<u8>> fromCache(key: String)
    Promise<bool> toCache(key: String, data: Array<u8>)
}

// Main entry point: kicks off the process of fetching a ipfs url,
// calling functions in `sink` as needed.
Cancelable fetchIpfs(url: Url, host: HostDelegate, sink: DataSink)

// Lower level api, fetching a CID
Cancelable fetchCID(cid: String, host: HostDelegate, sink: DataSink)
```

# Rust definition

```rust
pub trait DataSink {
    fn start(&self);
    fn stop(&self);
    fn error(&self, error: Error);
    fn data(&self, buffer: &[u8]);
}

pub trait Cancelable {
    fn cancel(&self);
}

#[async_trait]
pub trait HostDelegate {
    fn fetch_http<S: DataSink>(&self, url: &Url, sink: S) -> impl Cancelable;
    async fn dns_record(&self, name: &str, record: &str) -> Result<String>;
    async fn from_cache(&self, key: &str) -> Result<Vec<u8>>;
    async fn to_cache(&self, key: &str, data: &[u8]) -> Result<()>;
}


pub fn fetch_ipfs<H: HostDelegate, S: DataSink>(url: &Url, delegate: H, sink: S) -> impl Cancelable {
    todo!();
}

pub fn fetch_cid<H: HostDelegate, S: DataSink>(cid: &CID, delegate: H, sink: S) -> impl Cancelable {
    todo!();
}
````

# C ffi

```c
typedef struct ipfs_data_sink* ipfs_data_sink_ptr;
struct ipfs_data_sink
{
    void (*start)();
    void (*stop)();
    void (*error)(char *error);
    void (*data)(char *buffer, int len);
};

typedef void (*string_fn)(char *result);
typedef void (*buffer_fn)(char *buffer, int len);
typedef void (*void_fn)();

typedef ipfs_request_ptr void*;

typedef struct ipfs_host_delegate* ipfs_host_delegate_ptr;
struct ipfs_host_delegate
{
    ipfs_request_ptr (*fetch_http)(char *url, ipfs_data_sink_ptr sink);
    void (*dns_record)(char *name, char *record, string_fn callback);
    void (*from_cache)(char *key, buffer_fn callback);
    void (*to_cache)(char *key, char *buffer, int len, void_fn callback);
};

ipfs_data_sink_ptr new_ipfs_data_sink();
void free_ipfs_data_sink(ipfs_data_sink_ptr delegate);

ipfs_host_delegate_ptr new_ipfs_host_delegate();
void free_ipfs_host_delegate(ipfs_host_delegate_ptr delegate);

ipfs_request_ptr ipfs_fetch(char* url, ipfs_host_delegate_ptr host, ipfs_data_sink_ptr sink);

ipfs_request_ptr ipfs_fetch_cid(cid* url, ipfs_host_delegate_ptr host, ipfs_data_sink_ptr sink);

void ipfs_cancel_request(ipfs_request_ptr* request);
```
