> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pinata.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Signatures

> Learn how to use Pinata to cryptographically sign CIDs

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](/sdk/signatures/public) and the [Content Addressable Gateway Plugin](/gateways/plugins/content-addressable).

## Signature Standard

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

```typescript theme={null}
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](https://viem.sh/docs/actions/wallet/signTypedData).

<CodeGroup>
  ```typescript example.ts theme={null}
  import { account, walletClient } from './config'
  import { domain, types } from './data'

  const signature = await walletClient.signTypedData({
    account,
    domain,
    types,
    primaryType: 'Sign',
    message: {
      address: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
      cid: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4',
      date: "2024-07-29T18:29:47.355Z"
    }
  })
  ```

  ```typescript data.ts theme={null}
  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",
      },
    ],
  };
  ```

  ```typescript config.ts theme={null}
  import { createWalletClient, custom } from 'viem'
  import { mainnet } from 'viem/chains'

  export const walletClient = createWalletClient({
    chain: mainnet,
    transport: custom(window.ethereum!),
  })

  export const [account] = await walletClient.getAddresses()
  ↑ JSON-RPC Account

  // export const account = privateKeyToAccount(...)
  ↑ Local Account
  ```
</CodeGroup>

## 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](/sdk/signatures/public/add) method in the SDK.

```typescript theme={null}
import { PinataSDK } from "pinata-web3";

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

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

## Getting a Signature for a CID

There are two ways you can an existing signature for a CID: the [get](/sdk/signatures/public/get) method in the SDK or the [Content Addressable Gateway Plugin](/gateways/plugins/content-addressable).

### Content Addressable Gateway Plugin

After [installing the plugin](/gateways/plugins/getting-started#installing-plugins) you can simply request a CID through the Dedicated Gateway and get the signature in the header `pinata-signauture`.

```typescript theme={null}
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](/sdk/signatures/public/get) method to get a signature for a given CID.

<Note>
  This method will check all CIDs on Pinata and will return a signature if it exists
</Note>

```typescript theme={null}
import { PinataSDK } from "pinata-web3";

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

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

## Verifying a Signature

Since the signatures are using the EIP-712 standard you can use a library like [Viem](https://viem.sh/docs/utilities/verifyTypedData) to verify with the same typed data used to create it.

<CodeGroup>
  ```typescript example.ts theme={null}
  import { account, walletClient } from './config'
  import { domain, types } from './data'
  import { verifyTypedData } from 'viem'

  const CID = "bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4"

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

  const valid = await verifyTypedData({
    address: account.address,
    domain,
    types,
    primaryType: 'Sign',
    message: {
      address: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
      cid: 'bafkreih5aznjvttude6c3wbvqeebb6rlx5wkbzyppv7garjiubll2ceym4',
      date: "2024-07-29T18:29:47.355Z"
    },
    signature,
  })
  ```

  ```typescript data.ts theme={null}
  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",
      },
    ],
  };
  ```

  ```typescript config.ts theme={null}
  import { createWalletClient, custom } from 'viem'
  import { mainnet } from 'viem/chains'

  export const walletClient = createWalletClient({
    chain: mainnet,
    transport: custom(window.ethereum!),
  })

  export const [account] = await walletClient.getAddresses()
  ↑ JSON-RPC Account

  // export const account = privateKeyToAccount(...)
  ↑ Local Account
  ```
</CodeGroup>

## Removing a Signature for a CID

To delete an existing signautre for a given CID you can use the [delete](/sdk/signatures/public/delete) method.

```typescript theme={null}
import { PinataSDK } from "pinata-web3";

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

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