On-chain program
An Anchor program that holds credentials and gates buying. It enforces uniqueness exactly; the fuzzy part stays with the verifier.
Not deployed yet. The program ID will be published here when it is.
Accounts
| Account | Seeds | Fields |
|---|---|---|
Config | ["config"] | admin, verifier_authority, treasury, mint, price_lamports, credentials_issued, epoch_cap, epoch, issued_in_epoch |
HumanCredential | ["cred", wallet] | wallet, person_id, issued_at, revoked |
PersonLock | ["person", person_id] | person_id, bound_wallet |
UsedNonce | ["nonce", wallet, nonce] | none; its existence marks a pass as spent |
Both HumanCredential and PersonLock are created with Anchor's init, which fails if the account exists. That is the uniqueness rule: a second credential for a wallet, or a second wallet for a person ID, can't be created.
Instructions
| Instruction | Signer | Effect |
|---|---|---|
initialize_config | admin | Creates Config and the token mint (authority: Config). |
issue_credential(wallet, person_id) | verifier | Creates both PDAs. Limited to epoch_cap per Solana epoch. |
rebind_wallet(person_id, new_wallet) | verifier | Closes the old credential, opens one for the new wallet. Refused if revoked. |
revoke(wallet) | verifier or admin | Sets revoked. |
buy(amount) | buyer | Needs an unrevoked credential. Pays amount × price_lamports to the treasury, mints amount. |
buy_with_attestation(amount, nonce, expiry) | buyer | Same, plus a verifier-signed pass checked through the Ed25519 precompile. |
The buy pass
107 bytes, little-endian, signed by the verifier's ed25519 key:
"voicegate:attest:v1" 19 bytes program id 32 wallet 32 nonce u64 expiry i64, unix seconds amount cap u64, token base units
To use it, put two instructions in one transaction, in this order:
- An Ed25519 program instruction with
ed25519_instruction_datafrom/attestas its data and no accounts. All its offsets point into its own data. buy_with_attestation(amount ≤ cap, nonce, expiry), which reads the instruction right before it through the instructions sysvar.
The program refuses the purchase if the pass is signed by another key, names another wallet or program, has expired, or was already used.
Errors
| Code | Name |
|---|---|
6000 | Unauthorized |
6001 | EpochCapReached |
6002 | CredentialRevoked |
6003 | ZeroAmount |
6004 | MathOverflow |
6005 | MissingAttestation |
6006 | InvalidAttestation |
6007 | AttestationExpired |
6008 | AmountExceedsCap |