Image Uploads
Leverage Pinata + IPFS to add decentralized image uploads to your Farcaster client
While building a Farcaster client one of the most common things users will request after the ability to send casts is to add images or media to their casts, and thankfully Pinata makes this a breeze! In this doc we’ll show you how you can add Pinata IPFS uploads to your app no matter what stack you’re using.
The following guide will use Typescript but since this is using the Pinata API you can use whatever language you would like.
API Keys
The first thing you’ll need to do is visit the Pinata API Keys page to generate an API key.
In the ‘New Key’ modal, you can choose if you want the key to be an Admin key and have full access over every endpoint, or scope the keys by selecting which endpoints you want to use. You can also give it a limited number of uses, so be sure to give it a name to keep track of it. Once you have that filled out, click “Generate API Key” and it will show you the pinata_api_key
, pinata_api_secret_key
, and the JWT
. It’s best to click “Copy All” and keep the API key data safe and secure.
Once API keys have been created, you will not be able to see the secret or JWT again
Once you have created your keys you can go ahead and try testing them! Try to paste this into your terminal with your JWT
If successful you should see this!
Adding Uploads to Your Client
There are several approaches you can take to keep your API keys safe but the primary two we reccomend are:
- Send the file to your owner server via API so the server can upload to Pinata
- Create a temporary key using
/users/generateApiKey
on the server and upload via the client
In this guide we’ll show you second approach as it helps reduce the friction experienced when uploading larger file sizes (e.g. Next.js / Vercel has a limit of 4mb that can be sent via their API routes)
Key Generation
In our server code we’ll need a few endpoints with functions that will generate a temporary API key thats only valid for one use, then another to revoke the key just to be extra safe. If you were writing this in an API framework like Hono on a Cloudflare worker it would looke something like this.
In this code we have two endpoints, one for creating and one for revoking. In the creation we make an object with the key permissions, which in this case is just to pin a file and will only work once. After creating it we send back the key and the JWT which we’ll see used shortly. Then in the revoking we take that same pinata_api_key
as the value for apiKey
to identify what key we will be revoking. That’s it!
On the client side code, the functions to create and revoke that key might look something like this.
Uploading the File
Now that we have a temporary API key on the client, we can upload our file to IPFS from a client form. There are multiple ways to do different types of file uploads where are documented further here, but in short the Pinata API can accept readableStreams
from a local file system or blobs
. With the code below we’ll do a simple upload where the file is handled via React useState
.
Here we just pass in the keyData
we got from our server to access our one time use JWT
and send the request to Pinata. Once the upload is complete we’ll get a response that looks like this:
The IpfsHash
or CID is both the identifier and address for our content which we’ll access soon in sending a cast.
Adding the File Link to a Cast
Now that our content is uploaded, we can access it through our Dedicated Gateway using the following pattern:
Something else you might want to do is use the ?filename=
query at the end of the url to designate a filetype.
Here is an example of a fully functional Gateway URL
With this full image URL you can add it as a url
object in the embeds
array when sending a cast like so:
If you would like to see a fully completed client example using this method check out our open source Lite Client repo!