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 …. “
    }
}
7 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

1 Like