# CityZeen Canonical Token API Surface (Secondary Market)

This repository is the canonical implementation for token orchestration.
Geospatial and other products consume this API surface and must not fork token logic.

## Global API

- `window.CZ_SHARED_TOKEN_API.version`
- `window.CZ_SHARED_TOKEN_API.contractVersion`
- `window.CZ_SHARED_TOKEN_API.schema`
- `window.CZ_SHARED_TOKEN_API.readTokenState()`
- `window.CZ_SHARED_TOKEN_API.writeTokenState(payload)`
- `window.CZ_SHARED_TOKEN_API.transitionTokenState(payload)`
- `window.CZ_SHARED_TOKEN_API.checkEligibility(context)`
- `window.CZ_SHARED_TOKEN_API.validateAuditChain()`
- `window.CZ_SHARED_TOKEN_API.readAttestations()`
- `window.CZ_SHARED_TOKEN_API.upsertAttestation(payload)`
- `window.CZ_SHARED_TOKEN_API.prepareAttestationBridge(attestationId)`

## Geospatial Consumer Contract

- `window.CZ_GEOSPATIAL_TOKEN_CONTRACT.version`
- `window.CZ_GEOSPATIAL_TOKEN_CONTRACT.provider`
- `window.CZ_GEOSPATIAL_TOKEN_CONTRACT.api`

Geospatial must consume this contract and must not duplicate token logic.

## Required payload fields

### `transitionTokenState(payload)`

- `id` token state identifier
- `assetId` canonical asset id
- `fromState`
- `toState`
- `actor`
- `reason`
- `evidence`
- `idempotencyKey`

All transitions are written to the append-only audit chain.
Invalid target states are rejected by canonical core validation.
Replay attempts with the same `idempotencyKey` are blocked and audited.
State conflicts are rejected when `fromState` does not match current canonical state.

### `upsertAttestation(payload)`

- `id`
- `investorId`
- `walletAddress`
- `jurisdiction`
- `kycStatus`
- `amlStatus`
- `policyStatus`

No PII is written on-chain. Only claim hash bridge material is prepared via adapter.

## Security Guards

- Input validation is enforced for write methods.
- Text fields are sanitized and length-bounded before persistence.
- Audit chain can be verified with `validateAuditChain()`.
- Idempotency window is enforced in canonical core for transition writes.
