Skip to main content

Cardano API Additions

Although Cardano Rosetta Java is compliant with Rosetta Spec, some changes were added, mostly as metadata, as they contain Cardano specific information that needs to be either processed or returned.

To keep it easy, clear and upgradable for changes in the future, all specific metadata are added at the end of the API documentation.

To get a detailed view of the API and the changes, refer to the Rosetta API reference documentation.

Cardano Operation Types

Operations are used to represent components of transactions across the Rosetta API. They are returned from Data API endpoints and used by Construction API endpoints to build transactions.

Cardano Rosetta supports all operations available within the Cardano blockchain:

To support these operations, extra metadata is added to the standard Rosetta operation structure:

{
"withdrawalAmount": { "type": "Amount" },
"depositAmount": { "type": "Amount" },
"refundAmount": { "type": "Amount" },
"staking_credential": { "type": "PublicKey" },
"pool_key_hash": { "type": "string" },
"epoch": { "type": "number" },
"tokenBundle": { "type": "TokenBundleItem" },
"poolRegistrationCert": { "type": "string" },
"poolRegistrationParams": { "type": "PoolRegistrationParams" },
"voteRegistrationMetadata": { "type": "VoteRegistrationMetadata" },
"drep": { "type": "DRepObject" }
}

Endpoint specific changes

/search/transactions

Added block_identifier this enables the user to search for transactions within a particular block. Either index or hash must be set. If both are set from a different block, the returned list will be empty.

{
"block_identifier": {
"hash": "XXXXXX",
"index": "000"
}
}

This API can be disabled by setting DISABLE_SEARCH_API env variable to t, true or 1.

Max amount of transactions allowed to be requested is defined by PAGE_SIZE env variable, which is the same used at /block/transaction endpoint. Also, this value will be used if no limit parameter is received.

info

status and success filters are equivalent. If they are both set and they don't match, an error will be thrown. In the same way works address and account_identifier.address. status and maxBlock filters work as excluding filters, if they are set, besides operator value.

Pruning limitation

Searching for transactions by hash is always possible, because transaction records themselves are never pruned. However, searching by address is limited: address-based searches depend on the UTXO set, and once spent UTXOs older than the pruning window are deleted, only transactions involving current or recently spent UTXOs can be found by address. Older history is not returned once pruned.

/block

The following metadata is also returned, when querying for block information:

{
"transactionsCount": { "type": "number" },
"createdBy": { "type": "string" },
"size": { "type": "number" },
"epochNo": { "type": "number" },
"slotNo": { "type": "integer", "format": "int64" }
}

For transaction fields for the size and scriptSize are added to Transaction metadata.

{
"size": { "type": "integer", "format": "int64" },
"scriptSize": { "type": "integer", "format": "int64" }
}

/block/transactions

When the block requested contains transactions with multi assets operations, the token bundles associated to each operation will be returned as metadata as follows:

{
"metadata": {
"tokenBundle": [
{
"policyId": "3e6fc736d30770b830db70994f25111c18987f1407585c0f55ca470f",
"tokens": [
{
"value": "-5",
"currency": {
"symbol": "6a78546f6b656e31",
"decimals": 0
}
}
]
}
]
}
}
info

Assets will be returned sorted by name.

/account/balance

For accounts that have a multi asset balance, these will be returned with the corresponding policy passed as metadata at currency as follows:

{
"balances": [
{
"value": "4800000",
"currency": {
"symbol": "ADA",
"decimals": 6
}
},
{
"value": "20",
"currency": {
"symbol": "",
"decimals": 0,
"metadata": {
"policyId": "181aace621eea2b6cb367adb5000d516fa785087bad20308c072517e"
}
}
},
{
"value": "10",
"currency": {
"symbol": "7376c3a57274",
"decimals": 0,
"metadata": {
"policyId": "fc5a8a0aac159f035a147e5e2e3eb04fa3b5e67257c1b971647a717d"
}
}
}
]
}

When querying /account/balance, the result depends on the type of address:

  • For a payment address (Base or Enterprise), the response contains the sum of all unspent UTXOs for that address (the "spendable" balance).
  • For a stake address (reward address), the response contains only the available rewards that can be withdrawn from that stake address.

To present a wallet's total value, clients should query both the payment address (for spendable funds) and the stake address (for rewards), then combine the results.

Note on Stake Addresses

A stake address never holds UTXOs and cannot have a spendable balance. The /account/balance response for a stake address always reflects only the withdrawable rewards.

Internally, the Rosetta service gathers these two figures from different subsystems:

  • Spendable funds (ADA and native tokens) are obtained by summing all unspent UTXOs that belong to the payment address(es). These UTXOs are stored in the PostgreSQL database maintained by the Yaci Indexer.
  • Rewards balance is fetched directly from the Yaci Store through a lightweight internal HTTP call, which queries the current withdrawable rewards for the stake address.

As a consequence, the spendable portion updates whenever new blocks modify the UTXO set for the payment address, whereas the rewards portion changes only after the protocol distributes staking rewards (typically once per epoch).

/account/coins

warning

include_mempool is an optional parameter that can be used to include mempool transactions in the response. If not set, it will be ignored. Default is false, since mempool tracking is not activated by default as well. Note: Mempool functionality is not implemented yet.

/construction/derive

Following the Rosetta specification, this endpoint returns an Enterprise address by default. In addition to that, Cardano Rosetta Java allows the creation of Reward and Base addresses, which aren't supported in the Rosetta specification. Therefore, following optional parameters were added as metadata:

  • address_type: Either Reward, Base or Enterprise. It will default to Enterprise and will throw an error if any other value is provided.
  • staking_credential: The public key that will be used for creating a Base address. This field is only mandatory if the provided address_type is Base. It's ignored in other cases since the Reward and the Enterprise addresses are created with the public key already included in the request.

Examples

{
"network_identifier": {
"blockchain": "cardano",
"network": "mainnet"
},
"public_key": {
"hex_bytes": "159abeeecdf167ccc0ea60b30f9522154a0d74161aeb159fb43b6b0695f057b3",
"curve_type": "edwards25519"
},
"metadata": {
"address_type": "Base",
"staking_credential": {
"hex_bytes": "964774728c8306a42252adbfb07ccd6ef42399f427ade25a5933ce190c5a8760",
"curve_type": "edwards25519"
}
}
}

/construction/preprocess

Cardano transactions require a ttl (Time-to-live) to be defined. As it's explained in the Cardano docs, TTL represents a slot, or deadline by which a transaction must be submitted. The TTL is an absolute slot number, rather than a relative one, which means that the ttl value should be greater than the current slot number. A transaction becomes invalid once its ttl expires.

There are several restrictions that require a more complex workflow when defining ttl for a transaction:

  • ttl depends on the latest block slot number and Rosetta spec only allows online data to be fetched in /construction/metadata.
  • /construction/metadata only accepts parameters produced, without any modifications, by /construction/preprocess.

To be able to stay compliant with Rosetta spec but also let the user define a specific ttl, a new optional parameter relative_ttl within the metadata was introduced. If not set, a DEFAULT_RELATIVE_TTL will be used.

Additionally, deposit parameters can be added to the metadata, which are used to take staking and pool operations into account while calculating the transaction size.

Example metadata

{
"network_identifier": {
"blockchain": "cardano",
"network": "mainnet"
},
"operations": [...],
"metadata": {
"relative_ttl": "100",
"deposit_parameters": {
"poolDeposit": "500000000",
"keyDeposit": "2000000"
}
}
}

/construction/metadata

Metadata endpoint needs to receive the relative_ttl returned in process so it can calculate the actual ttl based on latest block slot number.

{
"metadata": {
"ttl": "65294",
"suggested_fee": [
{
"currency": {
"decimals": 6,
"symbol": "ADA"
},
"value": "900000"
}
]
}
}

/construction/payloads

Not only input and output operations are allowed but also special staking operations. Furthermore, transaction ttl needs to be sent as string in the metadata.

{
"metadata": {
"ttl": "65294"
}
}

/construction/parse

The request of this endpoint has no specific change but the response will have the operations parsed in the same way as the ones that are used to send as payload in the /construction/payloads and /construction/preprocess endpoints. This means that the order used in those two endpoints needs to be maintained exactly, otherwise the parse endpoint will not be able to reproduce the operations in the same order and the workflow will fail.

/construction/combine

In order to support Byron addresses an extra field called chain_code in the account_identifier's metadata of the corresponding signing_payload must be added when requesting to sign payloads. This value can be obtained by any of the Bip 32 Keys.

{
"signatures": [
{
"signing_payload": {
"account_identifier": {
"address": "addr1vxa5pudxg77g3sdaddecmw8tvc6hmynywn49lltt4fmvn7cpnkcpx",
"metadata": {
"chain_code": "dd75e154da417becec55cdd249327454138f082110297d5e87ab25e15fad150f"
}
},
"hex_bytes": "31fc9813a71d8db12a4f2e3382ab0671005665b70d0cd1a9fb6c4a4e9ceabc90",
"signature_type": "ed25519"
},
"public_key": {
"hex_bytes": "1B400D60AAF34EAF6DCBAB9BBA46001A23497886CF11066F7846933D30E5AD3F",
"curve_type": "edwards25519"
},
"signature_type": "ed25519",
"hex_bytes": "00000000000000000000000000"
}
]
}

Other considerations

Encoded transactions

Both signed_unsigned and unsigned_transaction don't correspond to a valid Cardano Transaction that can be forwarded to the network as they contain extra data required in the Rosetta workflow. This means that such transactions cannot be decoded nor sent directly to a cardano-node.

Transaction's metadata, needed for example for vote registration operations, is also encoded as extra data.

There is no expectation that the transactions which are constructed in Rosetta can be parsed by network-specific tools or broadcast on a non-Rosetta node. All parsing and broadcast of these transactions will occur exclusively over the Rosetta API.