Implement Rosetta Node API for Vite to allow easier integration with the Vite blockchain
vitelabs
api development, node.js, backend, golang
### Prize Title
Rosetta Node API for Vite
### Prize Bounty
$3000 **in VITE** + VITE merch
### Challenge Description
Looking for someone to build the Rosetta Node API for Vite (https://vite.org). Vite is an asynchronous, message-driven blockchain using a high-performance DAG-based ledger structured called block-lattice.
Rosetta is an OpenAPI standard (https://www.rosetta-api.org/docs/welcome.html) that makes integrating with blockchains simpler, faster, and more reliable. The Rosetta API is made up of 2 core components, the Data API and the Construction API. See [Rosetta Data API Overview](https://www.rosetta-api.org/docs/data_api_introduction.html) and [Rosetta Construction API Overview](https://www.rosetta-api.org/docs/construction_api_introduction.html) for details.
You can use any convenient programming language to implement the API. Rosetta provides the rosetta-sdk-go (https://github.com/coinbase/rosetta-sdk-go) to facilitate the work, which means if you are familiar with Golang, you could save a lot of time by using the SDK.
Future maintenance is not required after the final approval of your work.
### Submission Requirements
* The complete project should include a full implementation of all endpoints defined in the Data API and the Construction API, Docker deployment, and all source code
* The API must pass the rosetta-cli (https://www.rosetta-api.org/docs/rosetta_cli.html) validation
* All submissions, including all code, must be open source for future use and reference by the community, and links to external documents must be provided in the Github repo submission
* We will require a demo of the submission
### Judging Criteria
* The Vite team will run tests to make sure basic functions perform as required
* The code submitted will be subjected to a review for extensibility, organization, proper documentation
### Winner Announcement Date
* The Vite Labs team will schedule a demo after receiving the submission. And a winner will be announced within 48 hours after the demo
### Resources
* Vite documentation: https://docs.vite.org/
* Vite hackathon Reddit: https://www.reddit.com/r/vitelabs/comments/nwdalp/gr10_vite_hackathon_qa/
* Vite Discord: https://discord.gg/8WYncwsE
* Research: https://www.reddit.com/r/nanocurrency/comments/htcu8e/is_nano_compatible_with_the_rosetta_listing/ - Some comments on NANO about needing to have ledger pruning to properly implement Rosetta API
* Research: https://github.com/iotaledger/rosetta-iota - IOTA implementation (in Rust)
* Research: https://github.com/coinbase/rosetta-ethereum - golang implementation for Ethereum’s rosetta API, a decent reference given some similarity between gvite’s code and Ethereum’s geth (gvite is the Vite client)
### Follow Vite on social media
* https://twitter.com/vitelabs
* https://twitter.com/vitexexchange
* https://t.me/vite_en
* https://t.me/vitexexchange
**Vite Rosetta API Implementation Guideline**
# Vite Rosetta API Implementation Guideline
## Network
### /network/list
Returns a list of NetworkIdentifiers that the Rosetta server supports.
# Vite Rosetta API Implementation Guideline
## Network
### /network/list
Returns a list of NetworkIdentifiers that the Rosetta server supports.
Input example:
```json
{
"metadata": {}
}
```
Output example:
```json
{
"network_identifiers": {
"blockchain": "vite",
"network": "mainnet"
}
}
```
- The Rosetta server should identify what environment it is deployed in. The "network" field should be "testnet" or "mainnet".
### /network/options
This endpoint returns the version information and allowed network-specific types for a NetworkIdentifier. Any NetworkIdentifier returned by `/network/list` should be accessible here.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"metadata": {}
}
```
Output example:
```json
{
"version": {
"rosetta_version": "1.4.9",
"node_version": "2.10.0",
"metadata": {}
},
"allow": {
"operation_statuses": [
{
"status": "SUCCESS",
"successful": true
},
{
"status": "REVERTED",
"successful": false
},
{
"status": "EXCEED_MAX_DEPTH",
"successful": false
}
],
"operation_types": [
"REQUEST",
"CREATE_CONTRACT",
"MINT",
"RESPONSE",
"RESPONSE_FAIL",
"REFUND",
"GENESIS"
],
"errors": [
{
"code": 12,
"message": "Invalid account format",
"description": "This error is returned when the requested AccountIdentifier is improperly formatted.",
"retriable": true,
"details": {
"address": "0x1dcc4de8dec75d7aab85b567b6",
"error": "invalid Vite address"
}
}
],
"historical_balance_lookup": false,
"call_methods": [
],
"balance_exemptions": [
],
"mempool_coins": false
}
}
```
- "REQUEST" includes sending a transfer or calling a smart contract.
- "RESPONSE" stands for receiving a transfer or executing a contract function.
- "MINT" is the Coinbase transaction, including issuing SBP rewards and minting new token.
- "errors" should include all error types that could be used by the API.
### /network/status
This endpoint returns the current status of the network requested. Any NetworkIdentifier returned by `/network/list` should be accessible here.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"metadata": {}
}
```
Output example:
```json
{
"current_block_identifier": {
"index": 64122462,
"hash": "3fb1150cfb44e96311895acd633ca24655c1681669622397cfd85d9734e74a03"
},
"current_block_timestamp": 1624031822000,
"genesis_block_identifier": {
"index": 1,
"hash": "a53774e6b799726a6e978357527d10ffbeb563c584c109b75234999472e4082e"
},
"oldest_block_identifier": {
"index": 1,
"hash": "a53774e6b799726a6e978357527d10ffbeb563c584c109b75234999472e4082e"
},
"sync_status": {
"current_index": 64122462,
"stage": "2",
"synced": true
},
"peers": [
{
"peer_id": "c5c1f7fe672c74dc0f5cf19e9a7c6b3437caa92f2c871590a1a8ec2eabb43690",
"metadata": {
"name": "VM_NODE",
"version": 0,
"height": 64122569,
"address": "116.63.158.55:36452",
"flag": 0,
"superior": true,
"reliable": true,
"createAt": "2021-05-18 00:23:49",
"readQueue": 0,
"writeQueue": 0
}
}
]
}
```
## Block
### /block
Get a block by its Block Identifier. If transactions are returned in the same call to the node as fetching the block, the response should include these transactions in the Block object. If not, an array of Transaction Identifiers should be returned so /block/transaction fetches can be done to get all transaction information.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"block_identifier": {
"index": 59006949,
"hash": "c072c35dcf8a677f0e12c595c8e947b1635b5990ae95433bb693675d4a6ca2e0"
}
}
```
Output example:
```json
{
"block": {
"block_identifier": {
"index": 59006949,
"hash": "c072c35dcf8a677f0e12c595c8e947b1635b5990ae95433bb693675d4a6ca2e0"
},
"parent_block_identifier": {
"index": 59006948,
"hash": "41e2da1e92420fc36a3f1f7f30ada4ba2416f29a77a696744b05135a068af114"
},
"timestamp": 1618798789000,
"transactions": [
{
"transaction_identifier": {
"hash": "4a393aae72f0316f3c3dbfcb436109581083ad0623f864d8d55c163ebe1568ce"
},
"transaction_identifier": {
"hash": "1ed8c451981c4dcc822df994dd96f33d83620739b9ed78659057f3dfb51fbf11"
}
}
],
"metadata": {
"producer": "vite_aa7f76480db9e4072231d52f7b7abcccc8197b217a2dd5e818",
"publicKey": "4dYZBxadTgovIti9SGWyGZFLM7UlMohvoFM1lHRltgE=",
"signature": "PmquxeGuUAfOBec+nGnmDlGysdZscQoNsqQ1JuG5PjL7HA9mwlFavAM6feK7dDUToRCs/eqHsI6+m/EMzirqBQ==",
"seed": 13474976915601125056,
"nextSeedHash": "46ab323b3bd860345c1c5f6a6c49af244ed5c0867715a5252247e2973ce55360",
"version": 9
}
}
}
```
- On Vite, a block indicates snapshot block, not account block. An account block is a transaction, and will be used in /block/transaction.
- Use snapshot block related API, such as `ledger_getSnapshotBlockByHash` or `ledger_getSnapshotBlockByHeight`.
### /block/transaction
Get a transaction in a block by its Transaction Identifier.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"block_identifier": {
"index": 59006949,
"hash": "c072c35dcf8a677f0e12c595c8e947b1635b5990ae95433bb693675d4a6ca2e0"
},
"transaction_identifier": {
"hash": "4a393aae72f0316f3c3dbfcb436109581083ad0623f864d8d55c163ebe1568ce"
}
}
```
Output example:
```json
{
"transaction": {
"transaction_identifier": {
"hash": "4a393aae72f0316f3c3dbfcb436109581083ad0623f864d8d55c163ebe1568ce"
},
"operations": [
{
"operation_identifier": {
"index": 0
},
"type": "REQUEST",
"status": "Success",
"account": {
"address": "vite_1fa1ffa18bd75a14ce5940b1ffaee89ec86aadd5967d94c1cc",
},
"amount": {
"value": "-448000000000000000000",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
},
"metadata": {}
},
{
"operation_identifier": {
"index": 1
},
"related_operations": [
{
"index": 0
}
],
"type": "REQUEST",
"status": "Success",
"account": {
"address": "vite_0000000000000000000000000000000000000003f6af7459b9",
},
"amount": {
"value": "448000000000000000000",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
},
"metadata": {}
}
],
"related_transactions": [
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"transaction_identifier": {
"hash": "a1f23463bb4671b07d061acd3af1608d05d2d075dafa1017140bb2a44a4b8217"
},
"direction": "forward"
}
],
"metadata": {
"blockType": 2,
"height": "305",
"previousHash": "c12b2ddbf7b87e04b5e262933599945eeb74878506a315d6c3e55ab330c382ab",
"publicKey": "yKNP9HWmVbvqAdlbJ+/BNK8Z93L31DexnIFTnPSBM0A=",
"producer": "vite_1fa1ffa18bd75a14ce5940b1ffaee89ec86aadd5967d94c1cc",
"fromAddress": "vite_1fa1ffa18bd75a14ce5940b1ffaee89ec86aadd5967d94c1cc",
"toAddress": "vite_0000000000000000000000000000000000000003f6af7459b9",
"sendBlockHash": "0000000000000000000000000000000000000000000000000000000000000000",
"vmLogHash": null,
"sendBlockList": null,
"fee": "0",
"data": "0v01LQAAAAAAAAAAAAAAH6H/oYvXWhTOWUCx/67onshqrdUA",
"difficulty": "336736144",
"nonce": "EWnzl1slj0g=",
"signature": "2W6Jj2hNmt/tJumq3KjuYPylB2lutZnm7xcrXPM5RYjd/+GX+FGVa8m7XHJM6+R0d0+OxWTKygCQtd4+uAEJDg==",
"quotaUsed": "105000",
"confirmations": "5117127",
"firstSnapshotHash": "c072c35dcf8a677f0e12c595c8e947b1635b5990ae95433bb693675d4a6ca2e0",
"firstSnapshotHeight": "59006949",
"receiveBlockHeight": "105134",
"receiveBlockHash": "a1f23463bb4671b07d061acd3af1608d05d2d075dafa1017140bb2a44a4b8217",
"timestamp": 1618798789000
}
}
}
```
- "related_transactions" should be populated to identify the corresponding request transaction (having "direction": "backward") or response transaction (having "direction": "forward").
- Use `ledger_getAccountBlockByHash`
## Account
### /account/balance
Get an array of all AccountBalances for an AccountIdentifier and the BlockIdentifier at which the balance lookup was performed.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"account_identifier": {
"address": "vite_1fa1ffa18bd75a14ce5940b1ffaee89ec86aadd5967d94c1cc"
},
"currencies": [
{
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
}
]
}
```
Output example:
```json
{
"block_identifier": {
"index": 64214183,
"hash": "fc29bdcb851ba9ac73fb4e9227354d069f0d7b679887383d8ef8a28022d0e800"
},
"balances": [
{
"value": "35940099190604559",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
],
"metadata": {
"address": "vite_1fa1ffa18bd75a14ce5940b1ffaee89ec86aadd5967d94c1cc",
"blockCount": 317
}
}
```
- Should be able to query the balance of any token by tti.
- Use `ledger_getAccountInfoByAddress` to get balance.
## Construction
### /construction/derive
Derive returns the AccountIdentifier associated with a public key.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"public_key": {
"hex_bytes": " 36ccae62021fd60f8304ce137d89e6ef51e4806dcaf2b9f2b112d556fbbf2ce7",
"curve_type": "edwards25519"
},
"metadata": {}
}
```
Output example:
```json
{
"account_identifier": {
"address": "vite_d4426422a1885cb5b8660cfa98dfcf9ca93f1541d73e05b103",
"metadata": {}
},
"metadata": {}
}
```
### /construction/preprocess
Preprocess is called prior to /construction/payloads to construct a request for any metadata that is needed for transaction construction given (i.e. account nonce). The options object returned from this endpoint will be sent to the /construction/metadata endpoint UNMODIFIED by the caller (in an offline execution environment)
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"operations": [
{
"operation_identifier": {
"index": 0
},
"type": "REQUEST",
" account_identifier": {
"address": "vite_1ac61ca703636c24f2ba3c15ce24b976283672972e6944beb6",
"metadata": {}
},
"amount": {
"value": "-123808989999200000000",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
},
{
"operation_identifier": {
"index": 1
},
"related_operations": [
{
"index": 0
}
],
"type": "REQUEST",
"account": {
"address": "vite_9aeef0c5083494917bfb23d88bf590af755a08c75b9d7e6020",
},
"amount": {
"value": "123808989999200000000",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
},
"metadata": {}
}
],
"metadata": {
"use_pow": "true"
},
}
```
Output example:
```json
{
"options": {
"account_identifier": {
"address": " vite_1ac61ca703636c24f2ba3c15ce24b976283672972e6944beb6",
},
"fetch_previous_hash": "true",
"use_pow": "true"
}
}
```
- No need to populate fee related fields since there is no fees on Vite.
- There is no "status" for operations during construction.
- "fetch_previous_hash" should be set to true by default.
- "use_pow" should be set to false by default.
## /construction/metadata
Get any information required to construct a transaction for a specific network. Metadata returned here could be a recent hash to use, an account sequence number, or even arbitrary chain state.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"options": {
"account_identifier": {
"address": " vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
},
"fetch_previous_block": "true",
"use_pow": "true"
}
}
```
Output example:
```json
{
"metadata": {
"height": 23,
"previousHash": "2870a345482ab4382bfe9e6f56f916874582b23591487eb3e7e78405de5a41f2",
"difficulty": "67108863",
"nonce": "FWC0X7Za7HE="
}
}
```
- "account_identifier" indicates from which address the transaction will be sent.
- "account_block_height" and "previous_block_hash" are required to construct a transaction. You should get them from the blockchain by calling
1. [RPC] `ledger_getLatestAccountBlock` or
2. [Vite.js] `getPreviousAccountBlock` in AccountBlock class
- "difficulty" and "nonce" should be returned if “use_pow” is “true” in the request. "difficulty" can be obtained by calling `ledger_getPoWDifficulty`, and "nonce" is from `util_getPoWNonce`. If “use_pow” is not set, the two fields should not be populated.
## /construction/payloads
Payloads is called with an array of operations and the response from /construction/metadata. It returns an unsigned transaction blob and a collection of payloads that must be signed by particular AccountIdentifiers using a certain SignatureType.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"operations": [
{
"operation_identifier": {
"index": 0
},
"type": "RESPONSE",
"account_identifier": {
"address": "vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
"metadata": {}
},
"amount": {
"value": "-16400131475256580753",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
},{
"operation_identifier": {
"index": 1
},
"related_operations": [
{
"index": 0
}
],
"type": "RESPONSE",
"account_identifier": {
"address": "vite_1ac61ca703636c24f2ba3c15ce24b976283672972e6944beb6",
"metadata": {}
},
"amount": {
"value": "16400131475256580753",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
}
],
"metadata": {
"height": 23,
"previousHash": "2870a345482ab4382bfe9e6f56f916874582b23591487eb3e7e78405de5a41f2",
"difficulty": "67108863",
"nonce": "FWC0X7Za7HE=",
"blockType": 4,
"sendBlockHash": "8788c0933344f2136be5609adb1f18ae1d50c16be0a4f8500335695a2632b1e7",
"data": "8pxs4gAAAAAAAAAAAAAAAAAAAAA",
"fee": "0"
}
}
```
Output example:
```json
{
"unsigned_transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NCIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6ImYxMDU0YmZhOGFlMzBlNzk3MzYwNzJlOTg0YmIxZDU5ZGU1NzRjNGE2M2ZlNzg1YTUxMDZmOGRjMzI0YzMwZmEifQ==",
"payloads": [
{
"account_identifier": {
"address": "vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
"metadata": {}
},
"hex_bytes": "48304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd012103301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2",
"signature_type": "ed25519"
}
]
}
```
- On Vite, there is request transaction (A sends to B) and response transaction (B receives a tx from A). If "blockType" is 2, it is a request transaction. In this case, "sendBlockHash" is not required. For response transaction (having "blockType" 4) , "sendBlockHash" must be present.
- For constructing a response tx, in other words, receiving a transaction sent by others to you, you should call `ledger_getUnreceivedBlocksByAddress` to get the un-received tx list, then populate "sendBlockHash".
- "unsigned_transaction" is the raw transaction string in Base64, simply converted from the account block object. For example,
```js
Buffer.from(JSON.stringify(accountBlock), "utf8").toString('base64')
```
- "hex_bytes" is the raw payload. For example, you can use ```Buffer.from(payloads.payloads[0]).toString('hex')``` to populate this field.
## /construction/parse
Parse is called on both unsigned and signed transactions to understand the intent of the formulated transaction. This is run as a sanity check before signing (after /construction/payloads) and before broadcast (after /construction/combine).
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"signed": true,
"transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NCIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6ImYxMDU0YmZhOGFlMzBlNzk3MzYwNzJlOTg0YmIxZDU5ZGU1NzRjNGE2M2ZlNzg1YTUxMDZmOGRjMzI0YzMwZmEifQ=="
}
```
Output example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"operations": [
{
"operation_identifier": {
"index": 0
},
"type": "RESPONSE",
"account_identifier": {
"address": "vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
"metadata": {}
},
"amount": {
"value": "-16400131475256580753",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
},{
"operation_identifier": {
"index": 1
},
"related_operations": [
{
"index": 0
}
],
"type": "RESPONSE",
"account_identifier": {
"address": "vite_1ac61ca703636c24f2ba3c15ce24b976283672972e6944beb6",
"metadata": {}
},
"amount": {
"value": "16400131475256580753",
"currency": {
"symbol": "VITE",
"decimals": 18,
"metadata": {
"tti": "tti_5649544520544f4b454e6e40"
}
},
"metadata": {}
}
}
],
"metadata": {
"height": 23,
"previousHash": "2870a345482ab4382bfe9e6f56f916874582b23591487eb3e7e78405de5a41f2",
"difficulty": "67108863",
"nonce": "FWC0X7Za7HE=",
"blockType": 4,
"sendBlockHash": "8788c0933344f2136be5609adb1f18ae1d50c16be0a4f8500335695a2632b1e7",
"data": "8pxs4gAAAAAAAAAAAAAAAAAAAAA",
"fee": "0"
},
"account_identifier_signers": [
{
"address": " vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
"metadata": {}
}
]
}
```
## /construction/combine
Combine creates a network-specific transaction from an unsigned transaction and an array of provided signatures. The signed transaction returned from this method will be sent to the /construction/submit endpoint by the caller.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"unsigned_transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NCIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6ImYxMDU0YmZhOGFlMzBlNzk3MzYwNzJlOTg0YmIxZDU5ZGU1NzRjNGE2M2ZlNzg1YTUxMDZmOGRjMzI0YzMwZmEifQ==",
"signatures": [
{
"signing_payload": {
"account_identifier": {
"address": " vite_1737bb7abc4883cc2f415a804f80274d3a725a68a5bee5bad3",
"metadata": {}
},
"hex_bytes": " 48304502201fd8abb11443f8b1b9a04e0495e0543d05611473a790c8939f089d073f90509a022100f4677825136605d732e2126d09a2d38c20c75946cd9fc239c0497e84c634e3dd012103301a8259a12e35694cc22ebc45fee635f4993064190f6ce96e7fb19a03bb6be2",
"signature_type": "ed25519"
},
"public_key": {
"hex_bytes": " 36ccae62021fd60f8304ce137d89e6ef51e4806dcaf2b9f2b112d556fbbf2ce7",
"curve_type": "edwards25519"
},
"signature_type": "ed25519",
"hex_bytes": "clMrnk5pvZpoxgdYUIMBIzzz3RECTlUtcioQrtJe+yO1aMUftvIXNxs2iRZWqMuUBM7Zp1jz6tmuRGMFHpHzBg=="
}
]
}
```
Output example:
```json
{
"signed_transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NiIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6IjEyNjdkMzNhYWQ5MDc5NTkzYmY4NjMzYmY5ZmMzNWUwZTRiNjViMTUzNDA4ZmM5MWI3ZmRhMjQwY2RjNzQ3M2MiLCJwdWJsaWNLZXkiOiJXSFppbnhzbHNjRStXYUlxclVqR3Uyc2NPdm9yZ0Q0UStEUU9PY0RCdjRNPSIsInNpZ25hdHVyZSI6ImlqTW5wK2pzNmQzZ1NMZ1FoQUprUFdTTVFSb2szZkNaZFU2cklLcHM1S1g1eUJIRjBoUzZLQ2kvNkpHQ3lkVmN2VkJ3Y2F6WTVpNi9uN1ZlbVhZVENRPT0ifQ=="
}
```
## /construction/hash
TransactionHash returns the network-specific transaction hash for a signed transaction.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"signed_transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NiIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6IjEyNjdkMzNhYWQ5MDc5NTkzYmY4NjMzYmY5ZmMzNWUwZTRiNjViMTUzNDA4ZmM5MWI3ZmRhMjQwY2RjNzQ3M2MiLCJwdWJsaWNLZXkiOiJXSFppbnhzbHNjRStXYUlxclVqR3Uyc2NPdm9yZ0Q0UStEUU9PY0RCdjRNPSIsInNpZ25hdHVyZSI6ImlqTW5wK2pzNmQzZ1NMZ1FoQUprUFdTTVFSb2szZkNaZFU2cklLcHM1S1g1eUJIRjBoUzZLQ2kvNkpHQ3lkVmN2VkJ3Y2F6WTVpNi9uN1ZlbVhZVENRPT0ifQ"
}
```
Output example:
```json
{
"transaction_identifier": {
"hash": "98d4d397ebc4ad3516b0aa9a9c52e6be7a8e8061f3989b2ffe027ffa85510b49"
},
"metadata": {}
}
```
## /construction/submit
Submit a pre-signed transaction to the node.
Input example:
```json
{
"network_identifier": {
"blockchain": "vite",
"network": "mainnet"
},
"signed_transaction": "eyJibG9ja1R5cGUiOjIsImFkZHJlc3MiOiJ2aXRlX2FiMjRlZjY4Yjg0ZTY0MmMwZGRjYTA2YmVlYzgxYzlhY2IxOTc3YmJkN2RhMjdhODdhIiwiYW1vdW50IjoiMTAwMDAwMDAwMDAwMDAwMDAwIiwidG9rZW5JZCI6InR0aV81NjQ5NTQ0NTIwNTQ0ZjRiNDU0ZTZlNDAiLCJfdG9BZGRyZXNzIjoidml0ZV9jZWNjZTkxZWI1ZWQ0MDg3OTEwNWUxYzc4MGM1NzJkMDg3YmI2ZWM5MWRiMDQzZjQyMiIsImhlaWdodCI6IjI4NiIsInByb3ZpZGVyIjp7Il9wcm92aWRlciI6eyJFUlJPUlMiOnt9LCJqc29ucnBjIjp7fSwiX3JlcXVlc3RNYW5hZ2VyIjpbXSwiX3JlcXVlc3RJZCI6MSwidHlwZSI6Imh0dHAiLCJob3N0IjoiaHR0cDovLzE0OC43MC4zMC4xMzk6NDgxMzIiLCJ0aW1lb3V0Ijo2MDAwMCwiaGVhZGVycyI6W119LCJpc0Nvbm5lY3RlZCI6dHJ1ZSwicmVxdWVzdExpc3QiOltdLCJzdWJzY3JpcHRpb25MaXN0IjpbXSwiY3VzdG9tVHJhbnNhY3Rpb25UeXBlIjp7fX0sInByaXZhdGVLZXkiOiI5ZTNlMTg4NzdmMGQzOThmYmJmNGQ3YjM1MGRhNmExZDlkZDlkNDIwZTA2YTNkOWYzNzMzOGMwZDZjMWM5ZGM2NTg3NjYyOWYxYjI1YjFjMTNlNTlhMjJhYWQ0OGM2YmI2YjFjM2FmYTJiODAzZTEwZjgzNDBlMzljMGMxYmY4MyIsInByZXZpb3VzSGFzaCI6IjEyNjdkMzNhYWQ5MDc5NTkzYmY4NjMzYmY5ZmMzNWUwZTRiNjViMTUzNDA4ZmM5MWI3ZmRhMjQwY2RjNzQ3M2MiLCJwdWJsaWNLZXkiOiJXSFppbnhzbHNjRStXYUlxclVqR3Uyc2NPdm9yZ0Q0UStEUU9PY0RCdjRNPSIsInNpZ25hdHVyZSI6ImlqTW5wK2pzNmQzZ1NMZ1FoQUprUFdTTVFSb2szZkNaZFU2cklLcHM1S1g1eUJIRjBoUzZLQ2kvNkpHQ3lkVmN2VkJ3Y2F6WTVpNi9uN1ZlbVhZVENRPT0ifQ"
}
```
Output example:
```json
{
"transaction_identifier": {
"hash": "98d4d397ebc4ad3516b0aa9a9c52e6be7a8e8061f3989b2ffe027ffa85510b49"
},
"metadata": {}
}
```
- Decode the base64 transaction string into a signed account block, then call `ledger_sendRawTransaction`