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

# Identity & Attestations

> Deployable identity verifier and a generic on-chain attestation registry for Stellar (Soroban).

Every Ankara template can be gated by an **identity verifier**: on `mint` and on every
transfer, the token calls `is_verified(account)` on whatever contract is set as its
`identity_verifier`. Two contracts implement that interface on Stellar:

| Contract | Use it when |
| - | - |
| `whitelist-verifier` | You want a simple admin-managed allow-list (with optional expiry). Good default for pilots and dev. |
| `attestation-registry` | You want trusted third parties (a KYC provider, a land registry, a warehouse) to record facts that anyone can check later — KYC is one claim type among many. |

Both are Stellar-only and have no EVM counterpart beyond `WhitelistVerifier.sol`.

***

## whitelist-verifier

Soroban port of `WhitelistVerifier.sol` — admin-controlled allow-list implementing
`IdentityVerifierInterface`.

| Function | Access | Notes |
| - | - | - |
| `initialize(admin)` | once | |
| `verify(account)` | admin | never expires |
| `verify_until(account, expires_at)` | admin | unix seconds; `is_verified` turns `false` after it |
| `revoke(account)` | admin | |
| `batch_verify(accounts)` / `batch_revoke(accounts)` | admin | max 50 per call |
| `transfer_admin(new_admin)` | admin | e.g. hand over to a multisig |
| `is_verified(account)` | anyone | the verifier interface |
| `get_record(account)` | anyone | `{ verified_at, expires_at }` or none |

### Deploy

```bash theme={null}
cd packages/contracts-stellar
npm run build
VERIFIER=$(stellar contract deploy --wasm target/wasm32v1-none/release/whitelist_verifier.wasm --source deployer --network testnet)
stellar contract invoke --id $VERIFIER --source deployer --network testnet -- initialize --admin <ADMIN_ADDRESS>
```

Then point a token at it (at deploy time via `verifierAddress`, or later):

```ts theme={null}
import { AssetRegistry, WhitelistVerifier } from "@ankarachain/sdk";

const verifier = new WhitelistVerifier(stellarAdapter, VERIFIER);
await verifier.batchVerify(["GALICE...", "GBOB..."]);
await verifier.verifyUntil("GCAROL...", BigInt(Math.floor(Date.now() / 1000) + 365 * 86400));

const registry = new AssetRegistry(stellarAdapter, tokenAddress, "farmland");
await registry.setIdentityVerifier(VERIFIER);
```

***

## attestation-registry

A generic "someone trusted records a fact, anyone can verify it later" primitive.
An allow-listed **attestor** records a typed **claim** about a **subject**:

* **Subject** — `Account(address)` or `Asset(asset_id)` (the same 32-byte `asset_id` every template is initialized with; the SDK hashes your asset ID string the same way `TokenFactory` does).
* **Claim type** — a short `Symbol` you choose, e.g. `KYC`, `TITLE`, `DELIVERY`, `CREDIT`.
* **value** (`i128`) — numeric payload: KYC tier, credit score, quantity delivered, `1`/`0`.
* **data** (`String`) — anything else: document hash, registry reference, URI, small JSON.
* **expires\_at** — unix seconds, or `0` for never.

History is append-only: revoking a claim marks it `revoked` but keeps it readable.

| Use case | subject | claim\_type | value / data |
| - | - | - | - |
| KYC status | `Account` | `KYC` | tier (`> 0` = verified) |
| Land-title chain of custody | `Asset` | `TITLE` | — / new owner + deed hash |
| Delivery / harvest confirmation | `Asset` | `DELIVERY` | quantity / receipt hash |
| Credit / reputation signal | `Account` | `CREDIT` | score / model reference |

| Function | Access |
| - | - |
| `add_attestor(a)` / `remove_attestor(a)` / `set_verifier_claim_type(t)` | admin |
| `attest(attestor, subject, claim_type, value, data, expires_at) -> id` | attestor |
| `revoke(caller, id)` | the claim's attestor, or admin |
| `get_attestation(id)`, `latest(subject, type)`, `has_valid_claim(subject, type)` | anyone |
| `history(subject, type, start, limit)` (max 50), `claim_count(subject, type)` | anyone |
| `is_verified(account)` | anyone — verifier interface |

### As an identity verifier

The registry implements `is_verified` too: an account is verified when its latest
valid claim of the verifier claim type (default `KYC`) has `value > 0`. So a KYC
provider can be made an attestor and every template pointed straight at the registry.

```ts theme={null}
import { AttestationRegistry } from "@ankarachain/sdk";

const registry = new AttestationRegistry(adminAdapter, REGISTRY);
await registry.addAttestor("GKYCPROVIDER...");

// As the KYC provider:
const asProvider = new AttestationRegistry(providerAdapter, REGISTRY);
await asProvider.attest({ subject: { kind: "account", address: "GALICE..." }, claimType: "KYC", value: 2n });

// Land-title provenance for a deployed farmland token:
await asProvider.attest({
  subject: { kind: "asset", assetId: "FARM-OYO-2024-001" },
  claimType: "TITLE",
  value: 0n,
  data: JSON.stringify({ owner: "GBUYER...", deed: "0xabc..." }),
});
const chain = await registry.history({ kind: "asset", assetId: "FARM-OYO-2024-001" }, "TITLE");
```

### Deploy

```bash theme={null}
REGISTRY=$(stellar contract deploy --wasm target/wasm32v1-none/release/attestation_registry.wasm --source deployer --network testnet)
stellar contract invoke --id $REGISTRY --source deployer --network testnet -- initialize --admin <ADMIN_ADDRESS>
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.