In a post-AI world it will become more and more evident that every piece of content will need a cryptographic signature to verify it’s authenticity. Pinata is taking steps in this direction with the Signatures API and the Content Addressable Gateway Plugin.

Signature Standard

Pinata is using the EIP-712 signature standard for signing CIDs with the following domain and types.

export const domain = {
  name: "Sign Content",
  version: "1.0.0",
  chainId: 1,
} as const;

export const types = {
  Sign: [
    { name: "address", type: "address" },
    { name: "cid", type: "string" },
    { name: "date", type: "string" },
  ],
  EIP712Domain: [
    {
      name: "name",
      type: "string",
    },
    {
      name: "version",
      type: "string",
    },
    {
      name: "chainId",
      type: "uint256",
    },
  ],
};

address

  • Type: address

The wallet address of the user singing the CID

0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826

cid

  • Type: string

The target CID to be signed

bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4

date

  • Type: string

The date the target CID was first uploaded to Pinata

2024-07-29T18:29:47.355Z

Creating a Signature

In order to sign a CID you can use any library that support EIP-712 signing, like the example below with viem.

Adding Signature to CID

In order to attach a signature to a CID the following requirements must be met:

  • The CID being signed is owned by the signer
  • The CID being signed was first uploaded by the signer
  • The CID must not already have an existing signature with Pinata

After creating the signature with the previous step you can add it to the CID with the add method in the SDK.

import { PinataSDK } from "pinata-web3";

const pinata = new PinataSDK({
  pinataJwt: process.env.PINATA_JWT!,
  pinataGateway: "example-gateway.mypinata.cloud",
});

const signature = await pinata.signatures.add({
  cid: "QmXGeVy9dVwfuFJmvbzz8y4dYK1TdxXbDGzwbNuyZ5xXSU",
  signature: "0x1b...911b"
});

Getting a Signature for a CID

There are two ways you can an existing signature for a CID: the get method in the SDK or the Content Addressable Gateway Plugin.

Content Addressable Gateway Plugin

After installing the plugin you can simply request a CID through the Dedicated Gateway and get the signature in the header pinata-signauture.

const signatureReq = await fetch(
  `https://<YOUR_GATEWAY_DOMAIN>.mypinata.cloud/ipfs/<CID>`,
  {
    method: "HEAD",
  }
);
const signature = signatureReq.headers.get("pinata-signature");

SDK

You can also use the get method to get a signature for a given CID.

This method will check all CIDs on Pinata and will return a signature if it exists

import { PinataSDK } from "pinata-web3";

const pinata = new PinataSDK({
  pinataJwt: process.env.PINATA_JWT!,
  pinataGateway: "example-gateway.mypinata.cloud",
});

const signature = await pinata.signatures.get(
  "QmXGeVy9dVwfuFJmvbzz8y4dYK1TdxXbDGzwbNuyZ5xXSU"
);

Verifying a Signature

Since the signatures are using the EIP-712 standard you can use a library like Viem to verify with the same typed data used to create it.

Removing a Signature for a CID

To delete an existing signautre for a given CID you can use the delete method.

import { PinataSDK } from "pinata-web3";

const pinata = new PinataSDK({
  pinataJwt: process.env.PINATA_JWT!,
  pinataGateway: "example-gateway.mypinata.cloud",
});

const signature = await pinata.signatures.delete(
  "QmXGeVy9dVwfuFJmvbzz8y4dYK1TdxXbDGzwbNuyZ5xXSU"
);