An Image Proxy for use with NFTs

NFT are very popular right now, mainly in the art sector. Several wallets are working on support for viewing NFTs directly. This brings up issues of end user privacy and viewer safety. By communicating directly with NFT content hosted on third party portals, wallets run the risk of exposing the user to unmoderated content and leaking user attributes such as their IP address. We propose to build a standard and a reference implementation for a simple stateful proxy service that will sit between the wallets and the NFT content and address these issues.

As a first iteration we are planning the following:

  • The proxy will initially only support fetching image content and json based metadata.
  • Both IPFS and HTTPS resources can be fetched.
  • Automated content moderation will be applied by the proxy using providers such as AWS, Azure etc. Content deemed objectionable by the provider will be automatically blocked. Such content will only be served should the user explicitly specify that they wish to view the content. Moderation results will be cached by the service for some time.
  • Manual moderation via user reporting will also be supported. The service will keep track of reported content and based on some policy, mark it as unsafe.
  • A simple JSON based API which will allow wallets to make requests to fetch resources, describe the cached moderation metadata for a given resource and to allow users to report objectionable content. A draft API specification is provided below.
  • An open source implementation so anyone can run their own proxy service. Our github repo is available at https://github.com/Cryptonomic/ImageProxy

The Cryptonomic team is very open to suggestions and collaborations both in the proposed feature set and the API. Please leave a comment if you are interested.

Image Proxy API - Draft - Version 0.1

Kindly note that the following is a work in progress and is subject to change.

This is a JSON rpc based API. The API allows for the following functionality:

  1. Fetching an IPFS / HTTP resource
  2. Fetching moderation and other metadata for the resource
  3. Reporting a resource for violating guidelines

All endpoint invocations are done via HTTP POST calls. The content type for the request must be set to application/json. The return result type varies depending on the method invoked and the result of the invocation.

Additional HTTP headers that may be expected in the future:

  1. User Agent : To identify which client is connecting to the server
  2. Api Key : A pre-shared key without which client access is denied.

If a request is deemed unparsable by the server a HTTP 400 BAD REQUEST response will be returned.

Methods

img_proxy_fetch

Fetches a remote resource and applies content moderation if it is an image before returning the data. If moderation flags it, an error is returned.

Request Body:

{
 "jsonrpc":"1.0",
 "method":"img_proxy_fetch",
 "params": {
   “url”: “https://.... or ipfs://...."
   “force”: “true/false”
 }
}

Response:

  1. If content is deemed safe, set the following parameters in the response:
  • HTTP Status Code: 200 OK
  • Content Type: Set to whatever the remote server responded with.
  • Response Body: Set to whatever the remote server responded with.
  1. If content is deemed not safe and the force parameter has been set to true, set the following parameters in the response:
  • HTTP Status Code: 200 OK
  • Content Type: Set to whatever the remote server responded with.
  • Response Body: Set to whatever the remote server responded with.
  1. If content is not safe
  • HTTP Status Code: TBD (potentially 403 or 418)
  • Content Type: application/json
  • Response Body
{
  "jsonrpc": "1.0",
  "result": {
       “status”: “blocked”,
       “reason”: “Contains the following .......”
  }
}

img_proxy_describe

Returns metadata stored by the service for the specified resources including any moderation data.

Request Body:

{
 "jsonrpc":"1.0",
 "method":"img_proxy_describe",
 "params": { 
   “urls”: [ 
     “ipfs://....”, 
     “http://....”,
   ]
 }
}

Response:

  • HTTP Status Code: 200 OK
  • Content Type: application/json
  • Response Body:
{
  "jsonrpc": "1.0",
  "result": [
      { “url”: “ … “, “status”: “allowed/blocked/unknown”,  metadata: { …. TBD … } },
      ...
    ]
}

img_proxy_report

Allows a client to report a resource.

Request Body:

{
 "jsonrpc":"1.0",
 "method":"img_proxy_report",
 "params": { 
       “url”: “ipfs://.... or https://....”,
       “category” : "TBD"
       “reason”: “....”
    }
}

Response:

  • HTTP Status Code: 200 OK
  • Content Type: application/json
  • Response Body:
{
  "jsonrpc": "1.0",
  "result": {
      “url”: “..original url from request..“,
      “reportId”: “.... some UID …. “
    }
}
8 Likes

Wow! I want this so badly. I’ve been putting off the idea of an NFT display dapp because of this very issue. This is awesome. I’ll be watching for the release

2 Likes

Hi Everyone,

A quick update from the team. We have finished with our first version of the image proxy and are in the midst of final reviews and preparations for making a production instance available to you soon.

In the meanwhile, if you would like to try out the proxy for your own or perhaps start integrating it with your stack, we have two options available for you:

  1. For limited amount of time, we have a beta/preview version of the image proxy available at the url: https://imgproxy-preview.cryptonomic-infra.tech

  2. Instructions for setting up a local dockerized instance of your own. These are available in the repository.

API documentation is available on our github repository: GitHub - Cryptonomic/ImageProxy: Image Proxy for use with Wallets. The documentation includes examples which will work with the above preview server.

A few things to note:

  1. The proxy can fetch images from HTTP or IPFS urls only.

  2. The proxy supports fetching images of the following formats: jpg, png, tiff, gif, bmp. More formats will be added later.

  3. Moderation services are provided by AWS. Note that any results provided by moderation are suggestive in nature.

  4. An API key is required for making requests. A default key is provided in the examples within the API documentation. This key will work with both the preview server and a local dockerized instance.

  5. A javascript / typescript wrapper library is in the works to make integration with the proxy easy.

If you encounter any issues while trying out the proxy or have feature requests, comments or critiques, please open a github ticket. We will try to address them before our production release.

Thanks

1 Like

Hi,

This sounds really interesting, but a bit unclear on the objective. Is the API intended to obfuscate content uploader information and flag if the content is NSFW?

It’s intended to give dApp developers a set of re-usable tools for loading untrusted/unsafe IPFS content to the user’s web browser.

In plain English, this tool scrubs IPFS for things like embedded scripts and then implements an auto-content moderator, plus scales up in the cloud.

For example, Hicetnunc (very carefully) allows arbitrary scripts to be shown in their NFT displays. This allows for some cool stuff, but personally I wouldn’t want to expose my users to that risk. This tool allows me to scrub any IPFS before the end-user loads it.

After listening to your feedback, we are happy to announce that Nft Image Proxy is now live. With an updated RPC API and new typescript library, you can now easily integrate image moderation and filtering into your dapps. Request a free apikey to use our live instance at https://imgproxy-prod.cryptonomic-infra.tech by emailing infra@cryptonomic.tech. Or, run your own by following the directions here