Documentation
Build with Attestra
The SDK, the CLI, the MCP server, the contracts and the REST API. Everything here runs against NEAR testnet; one setting switches to mainnet.
Quick start
The packages are prepared for npm as @attestra/sdk, @attestra/cli and @attestra/mcp. From a clone of the repository:
pnpm install && pnpm build
# read anything, no keys needed
node packages/cli/dist/index.js schema known
node packages/cli/dist/index.js attestation fetch <uid>
# write with a testnet account from the NEAR CLI keychain
node packages/cli/dist/index.js -a you.testnet schema create \
-d "string name, u8 level" --revocableimport { AttestraClient } from '@attestra/sdk';
const client = new AttestraClient({ network: 'testnet' });
const r = await client.getAttestation(uid);
if (r.success) console.log(r.data.status); // active, revoked, expired...Concepts
Schema
The fields of a claim, an optional resolver and whether it can be revoked. Its UID is deterministic.
Attestation
A claim by an attester about a subject under a schema, with expiry, revocation and a nonce.
Authority
An issuer that registered itself; governance can verify it; staking gives it a tier.
Resolver
A contract that approves or refuses attestations and revocations for schemas that name it.
Delegate
An account allowed to attest (and maybe revoke) for an authority, within a scope.
Subject
A NEAR account or a CAIP-10 account on another chain.
Statuses
pending (waiting for a resolver), active, revoking, revoked (now or by schedule) and expired. Expiry and scheduled revocation are computed on every read.SDK
Every method returns ServiceResponse<T> (success, data, error.type, txHash) and never throws. Sign with a private key, a near-kit instance with a NEAR Connect wallet, or a key store.
// a key from env or the NEAR CLI keychain
new AttestraClient({ network: 'testnet', accountId: 'you.testnet', privateKey: process.env.KEY });
// a browser wallet (NEAR Connect)
import { Near, fromHotConnect } from 'near-kit';
const near = new Near({ network: 'testnet', wallet: fromHotConnect(connector) });
new AttestraClient({ network: 'testnet', accountId, near, indexerUrl });Schemas
| Method | What it does |
|---|---|
| registerSchema({ definition, resolver?, revocable }) | Register; returns the schema UID |
| getSchema(uid) | Read a schema |
| listSchemas({ authority?, limit?, offset? }) | List (indexer, or the contract) |
| storeSchemaBlob(definition) | Store a large definition (NEP-145) |
| getSchemaBlob(hash) | Read a blob |
| registerSchemaFromBlob({ blobHash, resolver?, revocable }) | Register by blob hash |
Attestations
| Method | What it does |
|---|---|
| createAttestation({ schemaUid, subject, data, expirationTime?, refUid? }) | Attest; status created or rejected |
| getAttestation(uid) | Read with live status |
| isValid(uid) | Active right now? |
| revokeAttestation(uid) | Revoke (attester only) |
| listAttestations({ schemaUid?, attester?, subject?, status? }) | List (indexer) |
| getNonce(account) | Next attestation nonce |
Authorities
| Method | What it does |
|---|---|
| registerAuthority(metadata, kind?) | Register or update |
| getAuthority(account) | Record with tier |
| setAuthorityVerification(account, verified) | Governance only |
| getProfile(account) | Issued, received, schemas |
Delegation
| Method | What it does |
|---|---|
| addDelegate(delegate, scope) | Grant with schemas, expiry, max uses, revoke right |
| removeDelegate(delegate) | Remove a grant |
| isDelegate(authority, delegate) | Active grant? |
| getDelegates(authority) | All grants |
| attestOnBehalf(params) | Attest as a delegate |
| revokeOnBehalf(uid) | Revoke as a delegate |
| addSignerKey(publicKey) | Key that may sign requests |
| signDelegatedAttestation(params, signer) | NEP-413 request, off chain |
| signDelegatedRevocation(params, signer) | NEP-413 revocation |
| submitSigned(request) | Submit yourself |
| relaySigned(request) | Relayer submits and pays |
Resolvers
| Method | What it does |
|---|---|
| whitelistAdd / whitelistRemove / whitelistCheck | Per schema |
| feeSetFee / feeGetFee / feeDeposit / feeGetBalance / feeCollected / feeWithdraw / feeWithdrawBalance | NEAR or NEP-141 |
| tokenGatedSetConfig / tokenGatedGetConfig | Minimum NEP-141 balance |
| tokenRewardSetConfig / tokenRewardFund / tokenRewardGetConfig / tokenRewardGetDistributed | Pay subjects |
| pipelineSetResolvers / pipelineGetResolvers | Chain resolvers |
| resolverInfo(resolver) / schemaAdmin(resolver, uid) | Inspect |
NEAR native
| Method | What it does |
|---|---|
| mintCredential(uid) / getCredential(uid) / listCredentials(owner) | NEP-171 credentials |
| scheduleRevocation(uid, at) / getScheduledRevocation(uid) / finalizeRevocation(uid) | Scheduled revocation |
| createMultisigAuthority / proposeMultisig / approveMultisig / executeMultisig / cancelMultisig / getMultisig / getProposal | k-of-n authorities |
| proposeDaoAttestation / proposeDaoRevocation / voteDaoProposal / getDaoProposals / getDaoPolicy / fundDaoStorage / createSputnikDao | Sputnik DAO attesters |
| stake / unstake / getStake / getTiers | Staking tiers |
| faucet() / tokenBalance(account) | Test token |
| listEvents(q) / proveAttestation(uid) / proveReceipt(id, receiver) | Audit trail and light client proofs |
Only on NEAR
| Method | What it does |
|---|---|
| requestPrivateCheck({ ruleId, subject, evidence }) | Private AI check |
| attestForeignEvent({ chain, txId, logIndex, log }) | Chain Signatures: an EVM log |
| attestForeignInstruction({ txId, instructionIndex, innerInstructionIndex }) | Chain Signatures: a Solana instruction |
| linkWalletMessage / linkWallet / linkedAccount | Wallets on other chains |
| registerAgent / delegateToAgent / rateAgent / getAgentProfile | Know Your Agent |
| grantAgentKey / revokeAgentKey / agentKeys | Function-call keys for agents |
| paidVerify(kind, target) | x402 paid verification |
For agents
import { getAttestraTools } from '@attestra/sdk/ai'; // LangChain
import { openAITools, runTool } from '@attestra/sdk'; // any OpenAI-compatible agent
const tools = openAITools(); // point the agent at https://cloud-api.near.ai/v1
const out = await runTool(client, 'verify_attestation', { uid });CLI
Every command takes --json. Signing commands take -a account and read its key from ~/.near-credentials or ATTESTRA_PRIVATE_KEY.
| Group | Commands |
|---|---|
| schema | create, fetch, list, uid, known |
| blob (large-schema) | store, fetch, register |
| attestation | create, fetch, verify, list, revoke |
| authority | register, fetch, verify |
| profile | <account> |
| storage | deposit, balance, withdraw |
| delegate | add, remove, list, check, attest, revoke, add-key, keys, sign, submit |
| whitelist | add, remove, check, info |
| fee | set-fee, get-fee, deposit, balance, collected, withdraw, refund |
| token-gated | set-config, get-config |
| token-reward | set-config, fund, get-config, distributed |
| pipeline (cross-contract) | set, get |
| credential | mint, fetch, list |
| schedule | revoke, status, finalize |
| multisig | create, propose-attest, propose-revoke, approve, execute, cancel, fetch, proposal |
| dao | info, propose-attest, propose-membership, propose-revoke, vote, proposals, proposal, fund, create |
| staking | stake, unstake, info, tiers |
| token | faucet, balance |
| events | list, prove, prove-receipt |
| check | run, rules |
| chain | link-message, link, linked, attest-event |
| agent | register, delegate, rate, profile |
| pay | verify-claim, verify-agent |
| encode / decode / config | offline helpers |
| ai | ask in natural language (NEAR AI Cloud) |
MCP server
Run it with one line for Claude Code, Codex or Claude Desktop, or use the hosted endpoint at /mcp on this site (read tools).
# Claude Code
claude mcp add attestra -- npx -y @attestra/mcp
# Codex (~/.codex/config.toml)
[mcp_servers.attestra]
command = "npx"
args = ["-y", "@attestra/mcp"]
# write tools: set ATTESTRA_ACCOUNT_ID and ATTESTRA_PRIVATE_KEY (testnet)| Tools | Kind |
|---|---|
| get_schema, list_schemas, well_known_schemas, get_attestation, verify_attestation, list_attestations, get_authority, get_delegates, get_agent_reputation, prove_attestation, linked_account, wallet_link_message, list_agent_keys, decode_data, compute_schema_uid, list_dao_proposals | read |
| register_schema, create_attestation, revoke_attestation, propose_dao_attestation, rate_agent, request_private_check, attest_foreign_event, attest_foreign_instruction, link_wallet, register_agent, delegate_to_agent, grant_agent_key, paid_verify | write: capped per tool and per day, deposits and payments capped per call |
Contracts
Rust, near-sdk 5.30, reproducible builds with NEP-330 metadata. Testnet accounts:
| Contract | Account |
|---|---|
| schemas | schemas.attestra.testnet |
| attestations | attestations.attestra.testnet |
| verdicts | verdicts.attestra.testnet |
| credentials | credentials.attestra.testnet |
| staking | staking.attestra.testnet |
| token (testnet) | token.attestra.testnet |
| resolvers | whitelist.attestra.testnet, fee.attestra.testnet, gated.attestra.testnet, reward.attestra.testnet, pipeline.attestra.testnet |
Verify any of them from a clone: near contract verify deployed-at attestations.attestra.testnet network-config testnet now.
REST API
The indexer reads NEP-297 events from FastNEAR's transactions API and re-reads every touched record from the contracts.
| Endpoint | Returns |
|---|---|
| GET /api/stats | Counts |
| GET /api/status | Indexer height, chain head, lag |
| GET /api/schemas?authority&resolver&search&limit&offset | Schemas |
| GET /api/schemas/:uid | One schema with its attestation count |
| GET /api/attestations?schema&attester&subject&status&limit&offset | Attestations |
| GET /api/attestations/:uid | One attestation, decoded |
| GET /api/authorities?verified&kind | Authorities |
| GET /api/authorities/:account | One authority with delegates |
| GET /api/agents, /api/agents/:account | Know Your Agent profiles |
| GET /api/events?event&contract&account&uid | NEP-297 audit trail |
| GET /api/profile/:account | Issued, received, schemas |
| GET /api/search?q | Universal search |
Encoding and UIDs
schema UID = sha256(borsh(("attestra:schema:v1", definition, resolver: Option<AccountId>, revocable)))
attestation UID = sha256(borsh(("attestra:attestation:v1", schema_uid [32], subject, attester, data: Vec<u8>, nonce: u64)))Data is the Borsh encoding of the fields in order. Types: bool, u8 to u128, i8 to i128, string, account_id, bytes, bytes32, and lists with [].
Only on NEAR
Private AI checks, cross-chain facts, Know Your Agent, paid verification, gasless issuing and light client proofs, each with its trust model, are described on the Only on NEAR page.
Networks
| Setting | Testnet |
|---|---|
| Switch | NEAR_NETWORK / NEXT_PUBLIC_NEAR_NETWORK = testnet | mainnet |
| RPC | https://test.rpc.fastnear.com |
| MPC signer | v1.signer-prod.testnet |
| Payment token (x402) | token.attestra.testnet |
| NEAR AI Cloud | https://cloud-api.near.ai/v1 |
| Explorer | https://testnet.nearblocks.io |