Skip to main content

Tezos

Tezos Reveal

On Tezos, an account that has never originated an outgoing operation has its public key only implied by its address hash. Before such an account can sign anything the network must verify, the public key has to be revealed on-chain — exactly once. Subsequent operations are then validated against that revealed key.

Custody exposes this one-time setup as:

  • a write endpoint that initiates a reveal custody transaction (subject to your vault’s normal approval workflow);
  • a read endpoint that returns whether a given address is currently revealed on the ledger.

Carabaas Custody also enforces an implicit guard on every regular Tezos transfer: outbound transactions from an un-revealed source are rejected at the API boundary. Plan your flow accordingly — see Reveal-before-transfer guard below.

Authentication: all calls require a valid JWT (same scheme as the rest of the Custody API).


Reveal-before-transfer guard

When you submit a regular Tezos transfer (POST /api/v1/transactions) and the source address is not yet revealed, the API rejects the request with HTTP 400 and the message Address is not revealed — the transfer is not created.

What this means for integrators:

  • The very first outbound activity of any Tezos vault address must be a reveal transaction. Only after it is confirmed on-chain can transfers from that address be initiated.
  • The check uses the same on-chain probe as the status read endpoint and adds a small Argus round-trip to every Tezos transfer creation; this is normal.
  • If your application creates an address and immediately tries to send from it, expect a 400 until reveal is confirmed.
  • Reveal status is per-address, persisted on-chain; once revealed, the address stays revealed forever.

A safe sequencing pattern:

  1. Create / select the Tezos source address.
  2. GET /addresses/{id}/is-revealed → if false, continue; otherwise skip to step 5.
  3. POST /transactions/reveal.
  4. Wait for the reveal transaction to reach confirmed (via webhooks / event stream).
  5. Submit transfers as usual.

Check if an address is revealed

Request

curl -H "Authorization: Bearer $TOKEN" \
https://api.carabaas.com/api/v1/addresses/{addressId}/is-revealed
MethodGET
Path/api/v1/addresses/{addressId}/is-revealed
Path parameteraddressId — Custody address resource id

No query parameters.

Authorization

The caller must satisfy either:

  • manageVaults permission on the address’s organization, or
  • read permission on the address’s vault.

Success response

  • HTTP 200
  • Body shape: { "data": { … } }
{
"data": {
"network": "tezos-mainnet",
"addressId": "8uPDmg3KsbUfsB8dx",
"networkAddress": "tz1abc...",
"revealed": true
}
}
FieldMeaning
networkCustody network code of the address.
addressIdThe same Custody address resource id you queried.
networkAddressThe on-chain Tezos address (tz1… / tz2… / tz3… / KT1…).
revealedtrue if the public key is revealed on-chain, otherwise false.

The probe queries chain state (via Custody’s wallet/indexer pipeline) at the time of the call — there is no caching layer between you and the ledger view, so it is suitable for gating UI actions such as enabling a “Send” button.

Error responses

HTTPWhen
400The address is not on a Tezos network (Only Tezos network is supported for this operation).
400The network is a virtual/test pseudo-network (Virtual networks are not supported for this operation).
400The address’s vault is paused, archived, or has no wallet attached (Vault is not active).
403Caller lacks both manageVaults (org) and read (vault) permissions.
404addressId does not exist in your organization scope.

Create a reveal transaction

warning

Run reveal before the first outgoing transfer from a Tezos address. Submitting a transfer from an un-revealed address fails with HTTP 400 (see Reveal-before-transfer guard).

Request

curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"orderId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"addressId": "8uPDmg3KsbUfsB8dx",
"network": "tezos-mainnet"
}' \
https://api.carabaas.com/api/v1/transactions/reveal
MethodPOST
Path/api/v1/transactions/reveal
BodyJSON (see below)

JSON body fields

FieldRequiredDescription
orderIdYesA valid UUID string. Used as an idempotency key: repeating the same orderId does not create a second transaction (see Idempotency).
addressIdYesCustody address resource id — the Tezos account that should be revealed. Must belong to an active vault that has a wallet attached.
networkYesCustody network code for a Tezos ledger (e.g. tezos-mainnet). Virtual/test pseudo-networks are not accepted.
feePriorityNoOne of low, medium, high. If omitted, the API applies its default fee behaviour for that network.

There is no asset field — reveal is asset-less; the operation pays its fee in XTZ, so the address must hold a small amount of XTZ to cover the fee before you submit.

Authorization

The caller must have initiate permission on the vault owning addressId. Without it the request is rejected with 403 before any transaction is created.

Idempotency and response codes

The JSON envelope follows the usual API pattern: { "data": { …transaction… } }. The HTTP status code distinguishes create vs replay — read it explicitly in addition to the body:

HTTPMeaning
201A new reveal transaction was created for this orderId.
200A transaction with this orderId already exists (idempotent retry); the same transaction object is returned.

Replays return the existing transaction regardless of its current status (pending, approved, broadcast, confirmed, failed, …), so data.status is the canonical signal for progress.

The returned transaction object has type: "reveal" and amount: "0" (a reveal carries no value transfer). It then moves through the same lifecycle as any other custody transaction: pending → approved (once vault quorum is met) → signing → broadcast → confirmed (or failed on rejection). Subscribe via your usual transaction-event channel (webhooks / event stream) to track it; do not assume the address is revealed until status is confirmed.

The reveal endpoint does not check current on-chain state before creating the transaction. If the address is already revealed on-chain, your reveal transaction will be rejected by the network at broadcast time and end up in failed status. Use GET /addresses/{id}/is-revealed first if you want to avoid this.

Error responses

All validation errors return HTTP 400 with a descriptive message. Common cases:

CauseMessage contains
network is not TezosNetwork ... is not allowed for this operation
network is a virtual/test pseudo-networkVirtual networks are not supported for this operation
Vault is paused, archived, or has no wallet attachedVault is not active
Caller lacks initiate on the vaultAccess denied (HTTP 403)
addressId does not exist(HTTP 404)

Schema-level violations (missing field, malformed UUID, wrong types) are rejected by request validation before any of the above and surface as a generic 400 with a Zod-style error.


Integration notes

  1. Fresh UUIDs, careful retries — Generate a fresh UUID per logical “reveal address” business action. On timeouts/network errors reuse the same orderId so retries don’t spawn duplicates: the server treats the retry as a no-op and returns the existing transaction with HTTP 200.
  2. Fund before reveal — A reveal still pays a small XTZ fee. Make sure the address holds enough native XTZ before you submit, otherwise the on-chain submission stage will fail even though the API call succeeds.
  3. One reveal per address, ever — Reveal is idempotent on chain only in the trivial sense that the network rejects double-reveals. Don’t treat reveal as something you may need to repeat; check status first if in doubt.
  4. Approvals required — Like any custody transaction, a reveal may need vault-quorum approvals before signing. Wire it through the same approval/notification path you already use for transfers.
  5. Gate “Send” UI on reveal — If your product surfaces a “Send” action for Tezos addresses, gate it on revealed === true (or on a successful, confirmed reveal in your own bookkeeping) to avoid hitting the reveal-before-transfer guard.
  6. Tezos only — Both endpoints reject other networks with 400.

See Also