> For the complete documentation index, see [llms.txt](https://docs.zkpass.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zkpass.org/developer-guides/js-sdk/generate-proof-and-verify-the-result/solana.md).

# Solana

### How to generate the proof with Solana?

```javascript
const generate = async (schemaId: string, appid: string) => {
    try {
      //check if you install the Phatom wallet
      if (!("phantom" in window)) {
        return alert("Please install Phantom wallet")
      }
      
      const provider = window.phantom?.solana
      const resp = await provider?.connect() //connect wallet
      const account = resp.publicKey.toString()

      //The appid of the project created in dev center     
      const appid = "39a00e9e-7e6d-461e-9b9d-d520b355d1c0"
      //The schemaId of the project
      const schemaId = "c7eab8b7d7e44b05b41b613fe548edf5"
            
      const connector = new TransgateConnect(appid)
      
      const isAvailable = await connector.isTransgateAvailable()
      if (!isAvailable) {
        return alert("Please install zkPass TransGate")
      }
      
      const res = (await connector.launchWithSolana(schemaId, account)) as Result

    } catch (err) {
      alert(JSON.stringify(err))
      console.log("error", err)
    }
  }
```

::: info The result includes two signatures: the allocator signature and the validator signature. Developers should verify both signatures based on the other returned fields. :::

### Verify Allocator Signature

#### Encode the allocator message struct

```javascript

import { Buffer } from "buffer"
import secp256k1 from "secp256k1"
import * as borsh from "borsh"
import sha3 from 'js-sha3'

//Attest struct for Solana
const SolanaTask = {
  struct: {
    task: 'string',
    schema: 'string',
    notary: 'string',
  },
}

const { taskId, allocatorSignature, validatorAddress } = res //return by Transgate

const sig_bytes = hexToBytes(allocatorSignature.slice(2));

const signatureBytes = sig_bytes.slice(0, 64);
const recoverId = Array.from(sig_bytes.slice(64))[0];

const plaintext = borsh.serialize(SolanaTask, {
    task: taskId,
    schema: schema,
    notary: validatorAddress,
 });

const plaintextHash = Buffer.from(sha3.keccak_256.digest(Buffer.from(plaintext)));

```

#### Recover the allocator address

```javascript
const signedAllocatorAddress = secp256k1.ecdsaRecover(signatureBytes, recoverId, plaintextHash, false);
```

#### Check if the signed allocator address is registered. The current allocator address is fixed.

```javascript
return signedAllocatorAddress === "69e7d686e612ab57e3619f4a19a567b3b212a5b35ba0e3b600fbed5c2ee9083d"
```

### Verify Validator Signature

#### Generate the validator message

```javascript
import { Buffer } from "buffer"
import secp256k1 from "secp256k1"
import * as borsh from "borsh"
import sha3 from "js-sha3"

//Attest struct for Solana
const Attest = {
  struct: {
    task: "string",
    schema: "string",
    nullifier: "string",
    recipient: "string",
    publicFieldsHash: "string",
  },
}

const { taskId, uHash, validatorAddress, schema, validatorSignature, recipient, publicFieldsHash } = res //return by Transgate
const sig_bytes = hexToBytes(validatorSignature.slice(2)) //skip the 0x

const signatureBytes = sig_bytes.slice(0, 64)
const recoverId = Array.from(sig_bytes.slice(64))[0]

const plaintext = borsh.serialize(Attest, {
  task: taskId,
  nullifier: uHash,
  schema,
  recipient,
  publicFieldsHash,
})

const plaintextHash = Buffer.from(sha3.keccak_256.digest(Buffer.from(plaintext)))
```

#### Recover the validator address

```javascript
 const signedValidatorAddress = secp256k1.ecdsaRecover(signatureBytes, recoverId, plaintextHash, false);
```

#### Verify if the signed validator address matches the address assigned by the allocator

```javascript
return signedValidatorAddress === validatorAddress
```

::: info Here, we've only given the reference code for js verification. However, the result can also be verified on Solana. :::


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.zkpass.org/developer-guides/js-sdk/generate-proof-and-verify-the-result/solana.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
