Identity & Access Overview
Accounts are the foundation for tokenization on Provenance Blockchain. By setting up accounts, onboarding users, verifying readiness, and managing permissions (including governance with multisig), you enable secure and efficient tokenization workflows.
What you'll build
- Onboard Users & Verify Account Readiness → Ship an Address Inspector: accept a name or address, normalize to Bech32, and check account info, balances/spendable, quarantined (pending) funds, and attributes.
- Manage Access, Permissions & Authorization → Implement least-privilege access: check fee coverage (Fee Grants) and allowed message types (Authorization Grants / Authz). When you need to enable or tighten permissions, use this cluster's Vault write flows and verify via the read endpoints here.
- Enable Governance (Multisig) → Make group governance visible (groups, members, policies, proposals, votes) and manage accordingly.
- Build Dashboards with Address Intelligence & Activity → Power dashboards with Plus (/v1) aggregates: priced balances, address metadata, and transfer-event search (cursor-paged).
Glossary: Key concepts
- Address: The human-readable identifier for an on-chain account (Bech32-encoded). On Provenance it starts with a network prefix (e.g., pb1…). It's derived from a public key and includes a checksum to catch typos.
- Bech32: The encoding used for addresses; includes a prefix (pb) and a checksum.
- nHash: Provenance's base/fee token used to pay network fees.
- Denom: A token identifier (e.g., nhash).
- Spendable: Funds / balance that an account can use right now (excludes escrow/vesting/locks).
- Quarantine: Incoming transfers that must be accepted/declined before they settle.
- Attribute: A verifiable label on an address (e.g., pio.kyc.verified).
- Grants: Fee grants (who pays fees for whom) and signing grants (which messages a key can send).
- Plus: Curated /v1 endpoints that return UI-ready aggregates so you don't have to stitch multiple protocol responses.
Before you start
Authentication
All calls below use the same gateway and require:
| Header | Value |
|---|---|
| Authorization | Bearer <TOKEN> |
| Content-Type | application/json |
(the spec marks them bearerAuth)
Don't have a token yet? If you don't have a token yet, use your tenant credentials or reach out to inbound@nuvalabs.com to get set up.
Base URLs
Declaring bases keeps code portable (dev/staging/prod; REST vs Plus vs Vault), and consistent with the rest of the docs:
# .env or shell exports (example)
export PROV_REST_BASE="https://api.provlabs.com" # Reads & writes (standard base)
export PROV_PLUS_BASE="https://api.provlabs.com" # Plus aggregates live under /v1/...
export PROV_VAULT_BASE="https://api.provlabs.com/vault" # Alternate mirror for same writes
export PROV_API_TOKEN="YOUR_BEARER_TOKEN"
In production, REST and Plus share the same host; Plus lives under /v1/....
How writes work in Accounts
Most Accounts-domain writes (Fee Grants, Authorization Grants, Attributes, Group/Multisig) follow the Provenance/Cosmos pattern: build an unsigned transaction with Vault, sign it with your key/HSM/wallet, broadcast via Node RPC, then verify with REST/Plus reads.
Note: For Digital Assets (markers/scopes), there are also direct POST/PATCH write operations under the standard base (see Tokenization → Fungible Tokens and Nonfungible Scopes). Use the approach that matches the operation.
Flow:
- Build an unsigned transaction in Vault (your Tx-builder API).
- Sign the Tx with your key.
- Broadcast the signed Tx via Node RPC (sync / async / commit).
- Verify state via REST reads (or Plus for UI aggregates).
In short: Vault builds unsigned txs → you sign → Node RPC broadcasts → REST/Plus verifies. This is the standard Cosmos pattern and the one NUVA Labs exposes.
Broadcast (RPC) — choose one per UX
curl -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"broadcast_tx_sync","params":["<BASE64_SIGNED_TX>"]}' \
"https://pio-mainnet-1-rpc.provlabs.com"
# ...or broadcast_tx_async / broadcast_tx_commit
See Node RPC Tx for more context → https://api.provlabs.com/rpc/docs
Why three surfaces (Vault, Node RPC, REST/Plus)?
- Vault (same bearerAuth) builds unsigned tx bodies for specific modules (feegrant, authz, attributes, group…).
- You sign the tx client-side with your key (HSM, wallet, service key).
- Node RPC broadcasts the signed tx (broadcast_tx_sync|async|commit). REST (and Plus /v1) are reads to verify state (and to power UI aggregates).
What is Vault (Tx Builder)? In this workflow, Vault refers to the Tx-builder surface on the /vault host: build tx messages (or batches), sign locally / commit, broadcast via Node RPC, then verify with REST/Plus reads. Note: /vault is a shared base and also hosts BlockVault (CEE/batch) and some read routes; here 'Vault' refers to the Tx-builder flows. SPEC →
Path prefixes you'll see All endpoints sit behind the same gateway; you'll encounter:
- /cosmos/... and /provenance/... for protocol reads
- /v1/... for Plus aggregates (e.g., /v1/addresses/...)
Common Authentication Errors
Missing or Invalid Authentication Token Scenario: The request is missing a valid authentication token or the token is invalid. Error Code: unauthenticated Example Request:
curl "$PROV_REST_BASE/cosmos/auth/v1beta1/account_info/pb1ADDRESS..."
Response:
{
"code": "unauthenticated",
"message": "Authentication token is missing or invalid."
}
How to handle: Ensure the Authorization header is included in the request: Authorization: Bearer <TOKEN>
- Verify that the token is valid and has not expired.
- If you don't have a token, contact inbound@nuvalabs.com to get set up.
Common Errors Summary
The following table summarizes common errors you may encounter when using the API:
| Error Code | Description |
|---|---|
| unauthenticated | Missing or invalid authentication token. |
| invalid_argument | Invalid input, such as an incorrectly formatted address or attribute name. |
| not_found | The requested resource (e.g., account, attribute) does not exist. |
| already_exists | The resource already exists (e.g., duplicate fee grant or authorization grant). |
| failed_precondition | A precondition for the request was not met (e.g., insufficient funds). |
| permission_denied | The caller does not have permission to access the resource. |
| resource_exhausted | The request exceeded resource limits (e.g., rate limits). |
| unavailable | The service is temporarily unavailable. |