Skip to content

Latest commit

 

History

History
451 lines (375 loc) · 14.5 KB

rosetta-custom-definitions.md

File metadata and controls

451 lines (375 loc) · 14.5 KB

Introduction

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

Endpoint specific changes

/construction/derive

By default this endpoint creates an Enterprise address but Cardano Rosetta also allows the creation of Reward and Base addresses, which aren't supported in the Rosetta specification. Therefore, following optional parameters are sent 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. These types are explained in the section 4 of the ledger specification.
  • staking_credential: the public key that will be used for creating a Base address and the format will be the same as the public key. 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

Base address

{
  "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"
    }
  }
}

Reward address

{
  "network_identifier": { "blockchain": "cardano", "network": "mainnet" },
  "public_key": {
    "hex_bytes": "964774728c8306a42252adbfb07ccd6ef42399f427ade25a5933ce190c5a8760",
    "curve_type": "edwards25519"
  },
  "metadata": { "address_type": "Reward" }
}

Enterprise address

In this case the metadata is optional. If it's provided, then the address_type should be "Enterprise" and the staking_credential could be anything since it will be ignored.

{
  "network_identifier": { "blockchain": "cardano", "network": "mainnet" },
  "public_key": {
    "hex_bytes": "1B400D60AAF34EAF6DCBAB9BBA46001A23497886CF11066F7846933D30E5AD3F",
    "curve_type": "edwards25519"
  },
  "metadata": {
    "address_type": "Enterprise",
    "staking_credential": {
      "hex_bytes": "1B400D60AAF34EAF6DCBAB9BBA46001A23497886CF11066F7846933D30E5AD3F__",
      "curve_type": "edwards25519"
    }
  }
}

/account/balance

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

Response

{
  "block_identifier": {
    "index": 382733,
    "hash": "50bb3491000528b19a074291bd958b77dd0b8b1cf3003bf14d1ac24a62073f1e"
  },
  "balances": [
    { "value": "4800000", "currency": { "symbol": "ADA", "decimals": 6 } },
   {
      "value": "20",
      "currency": {
        "symbol": "",                                                               // token symbol as hex string
        "decimals": 0,
        "metadata": {
          "policyId": "181aace621eea2b6cb367adb5000d516fa785087bad20308c072517e"    // token policy as hex string
        }
      }
    },
    {
      "value": "10",
      "currency": {
        "symbol": "7376c3a57274",
        "decimals": 0,
        "metadata": {
          "policyId": "fc5a8a0aac159f035a147e5e2e3eb04fa3b5e67257c1b971647a717d"
        }
      }
    }
  ],
  "coins": [...]
}

Also, coins will be returned with the token bundle list corresponding to each coin as metadata as follows:

{
  "block_identifier": {
    "index": 382733,
    "hash": "50bb3491000528b19a074291bd958b77dd0b8b1cf3003bf14d1ac24a62073f1e"
  },
  "balances": [...],
  "coins": [
    {
      "coin_identifier": {
        "identifier": "02562c123f6d560e1250f5a46f7e95911b21fd8a9fa70157335c3a3d1d16bdda:0"
      },
      "amount": {
        "currency": { "decimals": 6, "symbol": "ADA" },
        "value": "4800000"
      },
      "metadata": {
        "02562c123f6d560e1250f5a46f7e95911b21fd8a9fa70157335c3a3d1d16bdda:0": [       // coin identifier
          {
            "policyId": "181aace621eea2b6cb367adb5000d516fa785087bad20308c072517e",
            "tokens": [
              {
                "value": "20",
                "currency": {
                  "decimals": 0,
                  "symbol": "",
                  "metadata": {
                    "policyId": "181aace621eea2b6cb367adb5000d516fa785087bad20308c072517e"
                  }
                }
              }
            ]
          },
          {
            "policyId": "fc5a8a0aac159f035a147e5e2e3eb04fa3b5e67257c1b971647a717d",
            "tokens": [
              {
                "value": "10",
                "currency": {
                  "decimals": 0,
                  "symbol": "7376c3a57274",
                  "metadata": {
                    "policyId": "fc5a8a0aac159f035a147e5e2e3eb04fa3b5e67257c1b971647a717d"
                  }
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

/block

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

"transactionsCount": { "type": "number" }, // amount of transactions in the block
"createdBy": { "type": "string" },         // block creation time in UTC expressed as linux timestamp
"size": { "type": "number" },              // block size in bytes
"epochNo": { "type": "number" },           // epoch where the block has been included
"slotNo": { "type": "number" }             // block slot number

Request

{
  "network_identifier": { "blockchain": "cardano", "network": "mainnet" },
  "block_identifier": {
    "index": 100
  }
}

Response

{
  "block": {
    "block_identifier": {
      "hash": "a52cca923a67326ea9c409e958a17a77990be72f3607625ec5b3d456202e223e",
      "index": 100
    },
    "metadata": {
      "createdBy": "ByronGenesis-52df0f2c5539b2b1",
      "epochNo": 0,
      "size": 667,
      "slotNo": 99,
      "transactionsCount": 0
    },
    "parent_block_identifier": {
      "hash": "3d081d225a34a7ead8f12f8f7458a4994e40dc56322654abc04f41c8bb26c723",
      "index": 99
    },
    "timestamp": 1506205071000,
    "transactions": []
  }
}

/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:

Also, assets will be returned sorted by name.

Response

{
  "transaction_identifier": {
    "hash": "2356072a5379064aa62f83bf61d7d4467dbc47ec281461b558aa51b08c38c884"
  },
  "operations": [
    {
      "operation_identifier": {
        "index": 0
      },
      "type": "input",
      "status": "success",
      "account": {
        "address": "addr_test1vpcv26kdu8hr9x939zktp275xhwz4478c8hcdt7l8wrl0ecjftnfa"
      },
      "amount": {
        "value": "-999999000000",
        "currency": {
          "symbol": "ADA",
          "decimals": 6
        }
      },
      "coin_change": {
        "coin_identifier": {
          "identifier": "127cf01f95448cdcde439b8ace9b8a8ec100e690abe2b52069b3dbd924e032b3:0"
        },
        "coin_action": "coin_spent"
      },
      "metadata": {
        "tokenBundle": [
          {
            "policyId": "3e6fc736d30770b830db70994f25111c18987f1407585c0f55ca470f",
            "tokens": [
              {
                "value": "-5",
                "currency": {
                  "symbol": "6a78546f6b656e31",
                  "decimals": 0
                }
              }
            ]
          }
        ]
      }
    },
    ...
  ]
}

/construction/preprocess

Not only input and output operations are allowed but also special staking operations as described in here.

It is possible to operate with multi assets tokens too, as explained here.

Cardano transactions require a ttl to be defined. As it's explained in the cardano docs:

Time-to-live (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 be able to let consumers to configure ttl a new parameter was introduced:

metadata?: {
  relative_ttl: number;
};

If no relative_ttl is sent, a default one, DEFAULT_RELATIVE_TTL, will be returned.

Request

{
  "network_identifier": {
    "blockchain": "cardano",
    "network": "mainnet"
  },
  "operations": [...],
  "metadata": {
    "relative_ttl": 1000
  }
}

Response

{
  "options": {
    "relative_ttl": 1000,
    "transaction_size": 298
  }
}

/contruction/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.

Request

{
  "network_identifier": {
    "blockchain": "cardano",
    "network": "mainnet"
  },
  "options": {
    "relative_ttl": 1000,
    "transaction_size": 298
  }
}

Response

{
  "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 as described in here.

It is possible to operate with multi assets tokens too, as explained here.

If it is required to send a Catalyst vote registration, the information needed to do that can be found here

Furthermore, transaction ttl needs to be sent as string in the metadata.

Request

{
  "network_identifier": {
    "blockchain": "cardano",
    "network": "mainnet"
  },
  "operations": [...],
  "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 if the order used in those two endpoints needs to be exactly the one specified here. 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. So, the payload would look something like this:

{
  "network_identifier": {
    "blockchain": "cardano",
    "network": "mainnet"
  },
  "unsigned_transaction": "00000000000000000000000000",
  "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"
    }
  ]
}

This value can be obtained by any of the Bip 32 Keys. More information can be found (here)[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#extended-keys]. The creation of these type of addresses are not supported by Rosetta, to do so this link can be (useful)[https://github.com/Emurgo/cardano-serialization-lib/blob/master/doc/getting-started/generating-keys.md#use-in-addresses].

Other changes

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.

The rationale behind that decision can be found here:

The best way to get around this is for /construction/payloads to return additional metadata about the transaction which you may need later on for combining & parsing and wrapping the raw unsigned/signed transaction with this metadata. For example, in the UnsignedTransaction field of ConstructionPayloadsResponse, you can return a “rich” Sia transaction, which has additional info you need in /construction/combine.

[..] 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.

The same approach has been used to encode the operations that contain a staking key, since they couldn't be decoded otherwise.

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

/search/transactions

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.

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