{"id":19610700,"url":"https://github.com/onflow/rosetta","last_synced_at":"2025-04-27T22:33:01.026Z","repository":{"id":37843375,"uuid":"424277387","full_name":"onflow/rosetta","owner":"onflow","description":"Rosetta implementation for the Flow blockchain","archived":false,"fork":false,"pushed_at":"2025-03-31T18:58:27.000Z","size":511,"stargazers_count":16,"open_issues_count":8,"forks_count":9,"subscribers_count":35,"default_branch":"main","last_synced_at":"2025-03-31T19:37:36.532Z","etag":null,"topics":["rosetta"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-03T15:23:53.000Z","updated_at":"2025-03-31T18:58:30.000Z","dependencies_parsed_at":"2023-10-02T18:31:35.187Z","dependency_job_id":"a40feab4-7e50-432a-a91a-bf02dfcc6fc5","html_url":"https://github.com/onflow/rosetta","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frosetta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frosetta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frosetta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frosetta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onflow","download_url":"https://codeload.github.com/onflow/rosetta/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251219600,"owners_count":21554444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rosetta"],"created_at":"2024-11-11T10:32:05.442Z","updated_at":"2025-04-27T22:32:56.000Z","avatar_url":"https://github.com/onflow.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"This repo implements the [Rosetta API] for the [Flow blockchain].\n\n## Architecture\n\n```\n                   _____ _                 ____                _   _\n                  |  ___| | _____      __ |  _ \\ ___  ___  ___| |_| |_ __ _\n                  | |_  | |/ _ \\ \\ /\\ / / | |_) / _ \\/ __|/ _ \\ __| __/ _` |\n                  |  _| | | (_) \\ V  V /  |  _ \u003c (_) \\__ \\  __/ |_| || (_| |\n                  |_|   |_|\\___/ \\_/\\_/   |_| \\_\\___/|___/\\___|\\__|\\__\\__,_|\n\n\n\n     .───────────.\n    (   Client    )\n     `────┬▲─────'\n          ││\n          ││\n          ││\n          ││ Rosetta\n          ││ API\n          ││ Calls\n          ││\n          ││                                                                    /cmd/server\n  ┏━━━━━━━╋╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n  ┃       ││                                                                              ┃\n  ┃ ┌─────▼┴─────────────────────────────┐  ┌───────────────────────────────────────────┐ ┃\n  ┃ │                                    │  │                                           │ ┃\n  ┃ │         Rosetta API Server         │  │               State Indexer               │ ┃\n  ┃ │                                    │  │                                           │ ┃\n  ┃ └────┬────────────┬──────────────────┘  └─────────┬▲──────────────────────▲─────────┘ ┃\n  ┃      │            │                               ││                      │           ┃\n  ┃      │            │                        Processes Blocks        Validates Seals    ┃\n  ┃      │            │                       and Stores Data in           Against        ┃\n  ┃      │            │                         the Local Index         Consensus Data    ┃\n  ┃      │            │                               ││                      │           ┃\n  ┃      │            │                               ││                      │           ┃\n  ┃      │            │                               ││           ┌──────────┴─────────┐ ┃\n  ┃      │            │                               ││           │                    │ ┃\n  ┃      │   ┌────────┴─────┐          .─────────.    ││           │ Consensus Follower │ ┃\n  ┃      │   │              │         ╱           ╲   ││           │                    │ ┃\n  ┃      │   │   Data API   │◀───────(  Index DB   )◀─┘│           └───────────────────▲┘ ┃\n  ┃      │   │              │         `.         ,'    │                               │  ┃\n  ┃      │   └────────────▲─┘           `───┬───'      │       .─────────────────.     │  ┃\n  ┃      │                │                 │          │      ( Prefetch Workers  )    │  ┃\n  ┃      │                │                 │          │       `─────────────────'     │  ┃\n  ┃      │                │                 │          │                       │       │  ┃\n  ┃ ┌────┴──────────────┐ │                 ▼          │.─────────.            │       │  ┃\n  ┃ │                   │ │     .─────────────────.    ╱           ╲           │       │  ┃\n  ┃ │ Construction API  │ │    ( Balance Validator )  (  API Cache  )  Warms Up Cache  │  ┃\n  ┃ │                   │ │     `─────────────────'    `.         ,'           │       │  ┃\n  ┃ └─┬─────────────────┘ │       ▲                      `────▲──'◀────────────┘       │  ┃\n  ┃   │                   │       │                           │                        │  ┃\n  ┗━━━╋━━━━━━━━━━━━━━━━━━━╋━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━╋━━┛\n      │                   │       │                           │                        │\n      │                   │       │                           │                        │\n      │                   │       │                           │                        │\n      │                   │       │ Fetches                   │                        │\n      │                   │       │ On-Chain                  │                        │\n      │                   │       │ Balance                   │                        │\n      │    Fetches Recent │       │                           │                        │\n      │             State │       │                           │                        │\n      │                   │       │             Fetches Block │           Follows Live │\n      │                   │       │           Data and Events │        Spork Consensus │\n      │                   │       │             for Past/Live │         as an Unstaked │\n      │ Submits           │       │                    Sporks │            Access Node │\n      │ Transactions      │       │                           │                        │\n      │                   │       │                           │                        │\n      │                   │       │                           │                        │\n  ┏━━━▼━━━━━━━━━━━━━━━━━━━┻━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━┓ ┏━━━━━━━━━━━━━━━━━┻━━┓\n  ┃                                                                ┃ ┃                    ┃\n  ┃                    Flow Access API Servers                     ┃ ┃ Flow Access Nodes  ┃\n  ┃                                                                ┃ ┃                    ┃\n  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━━┛\n```\n\n## Overview\n\nFlow Rosetta consists of two primary systems:\n\n* The State Indexer:\n\n  * Uses the Access API servers to get the relevant block data and events for\n    each of the configured `sporks`.\n\n  * After establishing a data integrity chain from a trusted starting point,\n    processes the events for sealed blocks, and stores the inferred state\n    changes and block metadata in a local Index DB.\n\n  * Processes past sporks by starting with the root block data from the protocol\n    state snapshot of the live spork, and works backwards to the \"genesis\"\n    block, i.e. the configured \"root\" block of the first spork in the JSON\n    config.\n\n  * Processes the live spork by starting with the root block of that spork and\n    works forward to the most recently sealed block.\n\n  * Spins up a Consensus Follower, which is used to validate the seals for\n    blocks within a live spork.\n\n  * Spins up concurrent prefetch workers who cache various Access API calls in\n    advance of the main block processing loop.\n\n* The Rosetta API Server:\n\n  * This runs an HTTP server that implements various endpoints of the Rosetta\n    API.\n\n  * For the Rosetta Data API, the data primarily comes from the local Index DB.\n    For certain secondary bits of state, e.g. account sequence numbers, the\n    information is fetched from the Access API servers for the latest spork.\n\n  * For the Rosetta Construction API, the configured `construction_access_nodes`\n    are used to help get relevant metadata during transaction construction, and\n    for submitting the transactions.\n\n  * Runs a background balance validation loop that compares indexed account\n    balances against on-chain state whenever the indexer is synced close to tip.\n\n## Code Layout\n\nThe code is structured into the following top-level directories:\n\n* `access` — Provides a client for the Flow Access API that acts as a wrapper\n  around the gRPC Access API client.\n\n* `api` — The core Rosetta API server implementation.\n\n* `cache` — Provides a storage-backed cache layer for automatically caching\n  Access API calls.\n\n* `cli-conf` — Provides the default configuration for validating the implemented\n  Rosetta Data API against `rosetta-cli check:data`.\n\n* `cmd` — Provides the main command line binaries. Primary amongst these is the\n  `server` command.\n\n* `config` — Handles the JSON config file for Flow Rosetta.\n\n* `crypto` — Provides utility functions for converting between Rosetta and Flow\n  public key formats for secp256k1 keys.\n\n* `deque` — Provides a double-ended, auto-scaling queue for storing finalized\n  block IDs.\n\n* `environ` — Contains some minor build/test scripts.\n\n* `fees` — Defines the constants used to calculate fees during transaction\n  construction.\n\n* `indexdb` — Provides a storage-backed index for persisting the processed block\n  data.\n\n* `log` — Provides a thin wrapper for logging.\n\n* `model` — Defines the core protobuf-based data models used during transaction\n  construction and for persisting complex data within the `indexdb`.\n\n* `process` — Provides support for signal handlers and for automatically running\n  registered functions on process exit.\n\n* `script` — Contains the code for the Cadence transaction scripts and the code\n  for the Proxy contract.\n\n* `state` — Implements the State Indexer.\n\n* `timeout` — Provides some utilities for auto-extending timeouts on successful\n  I/O operations.\n\n* `trace` — Initializes the OpenTelemetry tracing/metrics infrastructure and\n  provides some thin wrappers for using them.\n\n* `version` — Defines the constants for the Flow and Flow Rosetta versions.\n\n## Shortcomings\n\nThis implementation has various shortcomings:\n\n* We use the events generated from Flow transactions to infer changes in account\n  balances. Since the events on Flow do not fully track the movement of\n  resources on-chain, these events will not 100% match the on-chain balance\n  changes.\n\n* In order to support balance reconciliation by `rosetta-cli check:data`, we\n  only track balance changes for accounts created by the configured\n  `originators` or any of its \"descendants\".\n\n* For our balance tracking of these accounts to remain valid, they must never be\n  used in any \"non-standard\" transactions, e.g. moving FLOW to non-default Vault\n  resources, splitting a withdrawal across multiple deposits, etc.\n\n* Since Flow effectively hard forks every spork, the Access API may serve block\n  data from an old spork that is then not part of the next spork. If the Rosetta\n  Node isn't shutdown in time, then it's possible for invalid data to be\n  processed and indexed.\n\n* We can partially mitigate this by restarting the Rosetta Node with an\n  appropriate block height to `resync_from`. However, if other services have\n  consumed the previously indexed data from the Rosetta Node, these will also\n  need to be reset.\n\n* Since the last few blocks in a spork don't have corresponding seals with\n  execution results, the events we receive for those blocks cannot be verified\n  through the Access API. It is therefore possible for us to process invalid\n  data for those blocks.\n\n* If the Access API servers aren't properly maintained and configured for\n  individual sporks, then it could result in data availability issues.\n\n* It needs to be actively reconfigured and restarted with every new spork. Some\n  of this data can be derived from the [sporks.json] data that is maintained by\n  Dapper Labs. If there are any delays or inaccuracies in those updates, this\n  would result in downtime.\n\n* Rosetta assumes that a transaction hash uniquely identifies a transaction\n  within a block. Unfortunately, in Flow, the same transaction hash can be\n  included multiple times within the same block by being included in different\n  collections.\n\n  * In responses to the `/block` endpoint, we default to using just the first\n    such transaction in a block, and will override it if any subsequent\n    transaction within the same block has any operations.\n\n## Installation\n\n```bash\n# download and install dependencies\nmake deps\n\n# build\nmake build\n```\n\n### Running interactively in Docker\n\n```\ndocker build -t flow .\n\ndocker run -it -v $(pwd):/app/src/rosetta-flow flow bash\n\n# first time\nmake\n\n# when making changes\nmake go-build\n\n./server \u003cpath/to/some-config.json\u003e\n```\n\n---\n\n_**Note:**_ Since [flow-go] can't be built like a normal Go module, you need to first\ncompile a [relic build] by running: `./environ/build-relic.py`. This is covered by the `make build` target.\n\nAnd then use `-tags relic` when building or running `cmd/server`.\n\n## Environment Variables\n\nThe Flow Rosetta `cmd/server` supports configuration of certain aspects via the\nfollowing environment variables:\n\n* `JSON_LOGS`\n\n  * Set this to `true` to enable JSON-formatted log output. If this value is not\n    set or set to a `false` value, it will default to \"human-readable\" log\n    output.\n\n* `OTEL_EXPORTER_OTLP_ENDPOINT`\n\n  * Use this to define a gRPC endpoint, e.g. `http://localhost:4318`, that can\n    be used to export OpenTelemetry traces and metrics using the OpenTelemetry\n    Protocol (OTLP).\n\n  * If this value is not set, all trace and metric data will simply be dropped\n    on the floor.\n\n* `DISABLE_BALANCE_VALIDATION`\n\n  * Set this to `true` to turn off the background balance validation loop. If\n    this value is not set or set to a `false` value, it will default to running\n    the balance validation loop.\n\n  * This should never be turned on in production.\n\n## JSON Config File\n\nThe Flow Rosetta `cmd/server` supports the following fields within the JSON\nconfig file:\n\n* `balance_validation_interval: string`\n\n  * The interval between every account check within the balance validation loop.\n    This accepts [time.Duration values](https://pkg.go.dev/time#ParseDuration)\n    like `\"1s\"`, `\"10ms\"`, etc. If no value has been set, this will default to 1\n    second.\n\n* `cache: bool`\n\n  * This can be used to enable the caching of idempotent Access API calls. This\n    should generally be set to `true` in production systems as it makes a\n    massive difference in a node's ability to be synced to tip.\n\n* `construction_access_nodes: []AccessAPIServerConfig`\n\n  * This defines a list of Access API servers that can be used during\n    transaction construction via the Rosetta Construction API.\n\n  * This must have at least one value for the Construction API to work, and the\n    given servers are used to submit transactions and to fetch data relevant for\n    transaction construction, e.g. reference block hash, fee calculations, etc.\n\n* `contracts`\n\n  * This defines the addresses for the key contracts on the specific Flow\n    network, e.g.\n\n```json\n{\n    \"flow_cold_storage_proxy\": \"0000000000000000\",\n    \"flow_fees\": \"f919ee77447b7497\",\n    \"flow_token\": \"1654653399040a61\",\n    \"fungible_token\": \"f233dcee88fe0abe\"\n}\n```\n\n  * Note: The addresses do not have a `0x` prefix, and if you do not have the\n    `FlowColdStorageProxy` contract deployed on the particular network, you must\n    use the zero address `\"0000000000000000\"` to disable support for proxy\n    accounts.\n\n* `data_dir: string`\n\n  * This defines the path to the data directory where the server stores data,\n    e.g. indexdb, cache store, etc.\n\n* `disable_consensus_follower: bool`\n\n  * This can be used to disable the use of Flow's Consensus Follower to validate\n    the block hashes and seals for blocks within live sporks.\n\n* `drop_cache: bool`\n\n  * This can be used to instruct Flow Rosetta to wipe the cache used for storing\n    idempotent Access API calls on startup. This primarily exists as an escape\n    hatch in case any of the existing protection against cache poisoning fails\n    for some reason.\n\n* `max_backoff_interval: string`\n\n  * When encountering certain API errors, we exponentially back off from two\n    seconds up to the given max backoff interval. This accepts [time.Duration\n    values](https://pkg.go.dev/time#ParseDuration) like `\"1s\"`, `\"30s\"`, etc. If\n    no value has been set, this will default to 10 seconds.\n\n* `mode: \"online\" | \"offline\"`\n\n  * This specifies whether the Flow Rosetta should work in online or offline\n    mode. During offline mode, only certain Rosetta API endpoints are\n    functional.\n\n* `network: \"mainnet\" | \"testnet\" | \"previewnet\" | \"localnet\"`\n\n  * This defines the specific Flow chain that is being used.\n\n* `originators: []string`\n\n  * This defines the set of root originator addresses. The addresses must be in\n    the standard hex-encoded format that Flow uses, but without the `0x` prefix.\n\n  * All root originator accounts must have been created after the configured\n    `root_block` of the first spork in the `sporks` definition. Otherwise, Flow\n    Rosetta will fail to index balance changes properly.\n\n* `port: uint16`\n\n  * This defines the port for the Flow Rosetta API server to listen on.\n\n* `purge_proxy_accounts: bool`\n\n  * This can be used to delete all proxy accounts from the indexed data on\n    startup. This is useful if you enabled support for proxy accounts at one\n    point, but would later like to remove it.\n\n  * Note: This still leaves behind the `IndexedBlock` data that might contain\n    operations relating to proxy accounts, which are used to generate responses\n    to the `/block` endpoint.\n\n* `resync_from: uint64`\n\n  * This can be used to tell Flow Rosetta to resync from a particular block\n    height on startup. This can be useful in dropping indexed data from any\n    blocks in the previous spork that are no longer part of Flow after a spork\n    upgrade.\n\n* `skip_blocks: []string`\n\n  * This can be used to instruct Flow Rosetta to skip certain data integrity\n    checks when processing any of the given block hashes.\n\n  * Note: The block hashes must be in the standard hex-encoded format that Flow\n    uses, and not use a `0x` prefix.\n\n* `spork_seal_tolerance: uint64`\n\n  * This defines the number of blocks at the end of a spork for which we expect\n    there to be no explicit seals. This is unfortunately required as Flow\n    self-seals the root block of a new spork, and doesn't provide seals for the\n    trailing blocks of the previous spork.\n\n  * This is a security risk as a compromised Access API server could send us\n    malicious event data that we will not be able to identify until after the\n    fact.\n\n* `sporks: map[string]SporkConfig`\n\n  * This defines a mapping of spork IDs to the spork config for the particular\n    set of sporks that we want to index.\n\n  * The ordering of the sporks is automatically inferred from the `root_block`\n    of each spork, so every spork after the \"first\" spork we define must have a\n    corresponding definition, and the \"last\" spork is inferred to be the current\n    live spork.\n\n* `workers: uint`\n\n  * This can be used to define the number of prefetch workers to use for warming\n    up the Access API cache. If unspecified, this will default to using twice\n    the number of CPUs available on the system.\n\nThe `AccessAPIServerConfig` supports the following fields:\n\n* `address: string`\n\n  * This defines the `host:port` for the Access API gRPC server.\n\n* `public_key: string`\n\n  * This should be set to a hex-encoded public key if the Access API gRPC server\n    is being served over a TLS connection where the server is using a libP2P\n    cert with the given public key.\n\n* `tls: bool`\n\n  * This should be set to `true` if the Access API gRPC server is being served\n    over a TLS connection where the server is using a DNS hostname and the cert\n    has been signed using one of the root Certificate Authorities on the host\n    system.\n\nThe `SporkConfig` supports the following fields:\n\n* `access_nodes: []AccessAPIServerConfig`\n\n  * This defines the list of Access API servers that will be used to fetch block\n    data for blocks within a spork.\n\n  * Flow Rosetta will randomly choose one of the given Access API servers for\n    each distinct set of requests.\n\n* `consensus: ConsensusConfig`\n\n  * This defines the config for the Consensus Follower. This must be defined\n    within the config for the current spork unless `disable_consensus_follower`\n    is specified in the top-level configuration.\n\n* `root_block: uint64`\n\n  * This defines the block height of the \"root\" block within a given spork.\n\n  * For the very \"first\" spork in `sporks`, this can point to any block within\n    that spork. This is so as to enable spinning up a new Flow Rosetta node\n    without having to sync from the start of a spork.\n\n  * The `root_block` of this \"first\" spork will be used as the \"genesis\" block\n    within that Flow Rosetta instance.\n\n  * For all subsequent sporks, the `root_block` must refer to the block height\n    of the actual root block within that spork.\n\n* `version: int`\n\n  * This defines the Flow Rosetta-specific version number that is used to\n    distinguish between the different data types and hashing mechanisms that are\n    used for block data integrity within sporks.\n\n  * As Flow doesn't define a versioning system for breaking changes in its data\n    integrity mechanisms, we define our own. This enables us to support multiple\n    sporks within the same code base and Flow Rosetta process.\n\nThe `ConsensusConfig` supports the following fields:\n\n* `disable_signature_check: bool`\n\n  * This can be used to disable the check of the PGP signature of the root\n    protocol state snapshot data.\n\n  * This should never be set in production.\n\n* `root_protocol_state_url: string`\n\n  * This defines the HTTPS URL for the file containing the JSON root protocol\n    state snapshot data for the live spork.\n\n* `root_protocol_state_signature_url: string`\n\n  * This defines the HTTPS URL for the file contained the armored PGP signature\n    of the root protocol state snapshot data.\n\n  * The signature needs to have been made by the key defined as the\n    `signing_key` value.\n\n* `seed_nodes: []SeedNodeConfig`\n\n  * This defines the Access Nodes that should be used to bootstrap the Consensus\n    Follower.\n\n* `signing_key: string`\n\n  * This defines the raw contents of the armored PGP key used to signed the root\n    protocol state snapshot data.\n\nThe `SeedNodeConfig` supports the following fields:\n\n* `host: string`\n\n  * This defines the host for the Access Node.\n\n* `port: uint16`\n\n  * This defines the port for the Consensus Follower to use for connecting to\n    the Access Node, usually `3570`.\n\n* `public_key: string`\n\n  * This defines the hex-encoded ECDSA P-256 public key for the Access Node.\n\n## FlowColdStorageProxy Contract\n\nTransactions in Flow currently expire after 600 blocks — roughly about 10\nminutes. This can be problematic for offline signing of transactions, e.g. for\ncold storage wallets, which can often take longer than the expiry window.\n\nIn order to support such cold storage transactions, we have created a\nFlowColdStorageProxy contract, `script/FlowColdStorageProxy.cdc` that allows for\nthe secure transfer of funds from cold wallets without being limited by Flow's\nexpiry window.\n\nIt works by using a \"meta transaction\":\n\n1. Cold keys sign an \"inner transaction\" payload which authorizes the transfer\n   of funds. This payload specifies the receiver address, amount, and inner\n   transaction nonce.\n\n2. Cold keys can take however long they need to sign this inner transaction.\n\n3. The payload and signature for the inner transaction are then passed in as\n   parameters of a `FlowColdStorageProxy.Vault#transfer` call within an \"outer\n   transaction\".\n\n4. The outer transaction can then be constructed and submitted by any account on\n   the network.\n\nThe `FlowColdStorageProxy` contract implements a `Vault` resource that wraps an\nunderlying `FlowToken.Vault`. We refer to accounts that have been set up with\nsuch a resource as a proxy account.\n\nThe following template provides the transaction script to create such a proxy\naccount:\n\n```cadence\nimport FlowColdStorageProxy from 0x{{.Contracts.FlowColdStorageProxy}}\n\ntransaction(publicKey: String) {\n    prepare(payer: AuthAccount) {\n        // Create a new account with a FlowColdStorageProxy Vault.\n        FlowColdStorageProxy.setup(payer: payer, publicKey: publicKey.decodeHex())\n    }\n}\n```\n\nBehind the scenes, `FlowColdStorageProxy.setup` will:\n\n1. Create a new Flow account. These accounts are created without any keys so as\n   to make their storage immutable except through exposed capabilities.\n\n2. Initialize a `FlowColdStorageProxy.Vault` resource with the given public key.\n\n3. Override the default `/public/flowTokenReceiver` with the\n   FlowColdStorageProxy Vault so that all deposits will be made directly into\n   it.\n\n4. Expose the default FlowToken Vault as `/public/defaultFlowTokenReceiver` so\n   that if the minimum account balance ever increases, this can be used to top\n   up the proxy account's default FLOW balance.\n\n5. Expose the FlowColdStorageProxy Vault as `/public/flowColdStorageProxyVault`.\n\nWhile calls to the `deposit` method are proxied by the FlowColdStorageProxy\nVault to the underlying FlowToken Vault, there is no corresponding `withdraw`\nmethod.\n\nInstead, funds must be transferred via the `transfer` method:\n\n```cadence\nfun transfer(receiver: Address, amount: UFix64, nonce: Int64, sig: [UInt8])\n```\n\nThis transaction script gives an example of how it can be used:\n\n```cadence\nimport FlowColdStorageProxy from 0x{{.Contracts.FlowColdStorageProxy}}\n\ntransaction(sender: Address, receiver: Address, amount: UFix64, nonce: Int64, sig: String) {\n    execute {\n        // Get a reference to the sender's FlowColdStorageProxy Vault.\n        let acct = getAccount(sender)\n        let vault = acct.capabilities.borrow\u003c\u0026{FlowColdStorageProxy.Vault}\u003e(FlowColdStorageProxy.VaultCapabilityPublicPath)!\n\n\n        // Transfer tokens to the receiver.\n        vault.transfer(receiver: receiver, amount: amount, nonce: nonce, sig: sig.decodeHex())\n    }\n}\n```\n\nThe intent of the code is that:\n\n* Funds held within a FlowColdStorageProxy Vault resource should only be\n  transferrable if the `FlowColdStorageProxy.Vault#transfer` \"inner transaction\"\n  has been signed by the `publicKey` specified during the\n  `FlowColdStorageProxy.setup` call.\n\n* Funds are protected against any replay attacks.\n\n* Funds must not be transferrable in any other way.\n\n* It should not be possible to move or destroy a FlowColdStorageProxy Vault\n  resource, and thus the underlying funds.\n\n* If the required minimum account balance requirement is ever increased, it\n  should be possible to deposit funds to the default FlowToken Vault by using\n  `/public/defaultFlowTokenReceiver` and ensure continued operations of an account\n  owning a particular FlowColdStorageProxy Vault instance.\n\n## Enabling Support for Proxy Accounts\n\nTo configure Flow Rosetta for proxy accounts, you need to first update\n`script/FlowColdStorageProxy.cdc` with the right network addresses for the\nimport statements, e.g.\n\n```cadence\nimport FlowToken from 0x0ae53cb6e3f42a79\nimport FungibleToken from 0xee82856bf20e2aa6\n```\n\nThen, you need to deploy the contract, e.g. using Flow CLI:\n\n```bash\n$ flow accounts add-contract \\\n  --network \u003cnetwork\u003e \\\n  --signer \u003ccontract-account\u003e\n  FlowColdStorageProxy ./FlowColdStorageProxy.cdc\nContract 'FlowColdStorageProxy' deployed to the account '01cf0e2f2f715450'.\n```\n\nAnd, finally, you need to update the `contracts.flow_cold_storage_proxy` value\nof the Flow Rosetta JSON config file with the address of the account to which\nthe contract has been deployed, e.g.\n\n```json\n\"contracts\": {\n    \"flow_cold_storage_proxy\": \"01cf0e2f2f715450\",\n    ...\n}\n```\n\nIf `contracts.flow_cold_storage_proxy` is set to `0000000000000000`, then proxy\naccount support will be disabled.\n\nIf you accidentally, enabled support for proxy accounts and want to later remove\nit, you need to first re-run Flow Rosetta with `purge_proxy_accounts` set to\n`true` in the JSON config file.\n\n## Supported Rosetta Operation Types\n\nWe support the following operation types as part of the Rosetta Construction API\nflow:\n\n* `create_account`\n\n* `create_proxy_account`\n\n* `deploy_contract`\n\n* `proxy_transfer`\n\n* `proxy_transfer_inner`\n\n* `transfer`\n\n* `update_contract`\n\nAll operations except for `proxy_transfer_inner` must specify the `payer`\naddress in the top-level request `metadata` field, i.e. outside of the\n`operations`.\n\nThe nonce/sequence number for a transaction can be specified as a `string` value\nin the top-level `metadata.sequence_number` field:\n\n* For `proxy_transfer_inner` operations, this refers to the nonce of the\n  FlowColdStorageProxy contract. For all other operations, it refers to the\n  sequence number of the payer's proposal key within the Flow transaction.\n\n* If this field isn't specified, then the latest on-chain value is looked up\n  during the `/construction/metadata` call.\n\n### Create Account(s)\n\nUse `create_account` to create a new account on Flow:\n\n```json\n[\n  {\n    \"type\": \"create_account\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"metadata\": {\n      \"public_key\": \"0395028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d23\"\n    }\n  }\n]\n```\n\nThe provided `metadata.public_key` needs to be a secp256k1 key in the SEC\ncompressed format used by Rosetta. Use the provided `cmd/formatkey` tool to\nconvert keys between Flow and Rosetta formats, e.g.\n\n```bash\n$ go run cmd/formatkey/formatkey.go from:flow 95028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d238f31c84c026a9ee2204176b77ccf77b999bc1a924c9ec2bd53bfd2db6cbe60c3\n0395028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d23\n\n$ go run cmd/formatkey/formatkey.go from:rosetta 0395028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d23\n95028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d238f31c84c026a9ee2204176b77ccf77b999bc1a924c9ec2bd53bfd2db6cbe60c3\n```\n\nMultiple `create_account` operations can be constructed within the same\ntransaction. The exact upper bound will depend on changes to Flow, but for now,\nup to 50 accounts can be comfortably created within the same transaction.\n\n### Create Proxy Account\n\nUse `create_proxy_account` to create a new proxy account, i.e. a new account set\nup with a FlowColdStorageProxy Vault:\n\n```json\n[\n  {\n    \"type\": \"create_proxy_account\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"metadata\": {\n      \"public_key\": \"0395028a149fe0c961ff9d3623fc83e2ecd1f35071c6725f7a4f495c9e13f23d23\"\n    }\n  }\n]\n```\n\nOnly one proxy account can be created within a single transaction, and the\n`metadata.public_key` refers to the public key for the FlowColdStorageProxy\nVault itself, and not the account.\n\n### Deploy Contract\n\nUse `deploy_contract` to deploy a contract to a `payer` account:\n\n```json\n[\n  {\n    \"type\": \"deploy_contract\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"metadata\": {\n      \"contract_code\": \"70756220636f6e74726163742048656c6c6f576f726c64207b0a202020207075622066756e2068656c6c6f28293a20537472696e67207b0a202020202020202072657475726e202248656c6c6f20776f726c6421220a202020207d0a7d0a\",\n      \"contract_name\": \"HelloWorld\",\n      \"key_message\": \"some message to sign\",\n      \"key_metadata\": \"key_id: 1234\",\n      \"key_signature\": \"3044022034d188e2aa3c5e6c65b323c400b536b268b2326b49f1d69467753ffc0a5ad538022051e8e9552deddea020b174dfc3d4c91d1c435867010f73c38d1c760817069e47\",\n      \"new_key\": \"025a7a5a204e7207c02121f5444a47ec29cc34495926b7136ea1e2169dd5445dcc\",\n      \"prev_key_index\": 0\n    }\n  }\n]\n```\n\nThe contract code needs to be hex-encoded. You can do this on the command-line\nby piping the source code into something like:\n\n```bash\n$ cat file.cdc | hexdump -v -e '/1 \"%02x\"'\n```\n\nThe `key_signature` needs to be a valid ECDSA signature with the given `new_key`\nover the SHA2-256 hash of the specified `key_message`. The `key_metadata` field\ncan be any arbitrary string. It's only passed in as a parameter to leave an\non-chain audit trail, and is not stored anywhere else.\n\nThe `prev_key_index` must be the key index of the most recently set key. This\nkey will be revoked as part of the deploy transaction.\n\nNote: Once a `deploy_contract` transaction has been submitted and lands on\nchain, there will be no corresponding operation within the transaction's\n`/block` response except for the deducted fee from the `payer`.\n\n### Transfer\n\nUse `transfer` to send funds from a normal account to any other account, e.g. to\nsend 0.2 FLOW from `0xddac9f33298b6e79` to `0xb73aff1e77717543`:\n\n```json\n[\n  {\n    \"type\": \"transfer\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"account\": {\n      \"address\": \"0xddac9f33298b6e79\"\n    },\n    \"amount\": {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"-20000001\"\n    }\n  },\n  {\n    \"type\": \"transfer\",\n    \"operation_identifier\": {\n      \"index\": 1\n    },\n    \"related_operations\": [\n      {\n        \"index\": 0\n      }\n    ],\n    \"account\": {\n      \"address\": \"0xb73aff1e77717543\"\n    },\n    \"amount\": {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"20000001\"\n    }\n  }\n]\n```\n\nNote: We currently expect the \"sender\" of a `transfer` to be the exact same\naccount as the `payer`.\n\n### Proxy Transfer\n\nUse `proxy_transfer` to send funds from a proxy account to any other account,\ne.g. to send 0.2 FLOW from `0xddac9f33298b6e79` to `0xb73aff1e77717543`:\n\n```json\n[\n  {\n    \"type\": \"proxy_transfer\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"account\": {\n      \"address\": \"0xddac9f33298b6e79\"\n    },\n    \"amount\": {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"-20000001\"\n    }\n  },\n  {\n    \"type\": \"proxy_transfer\",\n    \"operation_identifier\": {\n      \"index\": 1\n    },\n    \"related_operations\": [\n      {\n        \"index\": 0\n      }\n    ],\n    \"account\": {\n      \"address\": \"0xb73aff1e77717543\"\n    },\n    \"amount\": {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"20000001\"\n    }\n  }\n]\n```\n\n### Update Contract\n\nUse `update_contract` to update an existing contract on a `payer` account:\n\n```json\n[\n  {\n    \"type\": \"update_contract\",\n    \"operation_identifier\": {\n      \"index\": 0\n    },\n    \"metadata\": {\n      \"contract_code\": \"70756220636f6e74726163742048656c6c6f576f726c64207b0a202020207075622066756e2068656c6c6f28293a20537472696e67207b0a202020202020202072657475726e202248656c6c6f20746865726521220a202020207d0a7d0a\",\n      \"contract_name\": \"HelloWorld\",\n      \"key_message\": \"some message to sign\",\n      \"key_metadata\": \"key_id: 1234\",\n      \"key_signature\": \"3044022034d188e2aa3c5e6c65b323c400b536b268b2326b49f1d69467753ffc0a5ad538022051e8e9552deddea020b174dfc3d4c91d1c435867010f73c38d1c760817069e47\",\n      \"new_key\": \"025a7a5a204e7207c02121f5444a47ec29cc34495926b7136ea1e2169dd5445dcc\",\n      \"prev_key_index\": 1\n    }\n  }\n]\n```\n\nNote: Once an `update_contract` transaction has been submitted and lands on\nchain, there will be no corresponding operation within the transaction's\n`/block` response except for the deducted fee from the `payer`.\n\n## Example Originator\n\nFor the below examples, we will first generate a key for our root originator:\n\n```bash\n$ go run cmd/genkey/genkey.go\nPublic Key (Flow Format): 7509387372ee7ded90281fe21dc5b250b609bacc516da473756d7f190ec2bce73aa5ad760610da452142f61fd6714f871fbd261840a4907ee3253d33d6aa9186\nPublic Key (Rosetta Format): 027509387372ee7ded90281fe21dc5b250b609bacc516da473756d7f190ec2bce7\nPrivate Key: 914bf493aacd199c1f4f2f19d3f80ef69066307d39d7f4ccfe298ab76fbee0b5\n```\n\nThis key will be registered with a new account created at address\n`0xd99b1eba9b561cfa`.\n\nFor the purposes of this example, we created this originator via the [Flow\nTestnet Faucet], but this will probably be done by some kind of key management\nsystems in production systems.\n\n[Flow Testnet Faucet]: https://testnet-faucet.onflow.org/\n\n## Creating Accounts via the Rosetta Construction API\n\nFlow requires accounts to be created with specific public keys on-chain before\nthey can be used. Our implementation provides a `create_account` operation type\nto support this via the Rosetta Construction API.\n\nThe following provides a high-level walkthrough of the request/response flows\nfor creating accounts via the API.\n\nFirst, generate a key:\n\n```bash\n$ go run cmd/genkey/genkey.go\nPublic Key (Flow Format): bd7bfdb6297207619eb9907a39f512ac2861f45e5ba52cfaa777b6e7fa9aab6c45522faa013c1491627bb534fdbcae3f0545982f6bf77b665bc162ebf2592484\nPublic Key (Rosetta Format): 02bd7bfdb6297207619eb9907a39f512ac2861f45e5ba52cfaa777b6e7fa9aab6c\nPrivate Key: dc915efc3992d2c59b69de4948d565ac953818d9ccee78b65df590764786ada0\n```\n\nUse the Rosetta format of the public key as the `metadata.public_key` within the\n`create_account` operation, and our originator as the top-level `metadata.payer`\nin the call to `/construction/preprocess`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"create_account\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"metadata\": {\n        \"public_key\": \"02bd7bfdb6297207619eb9907a39f512ac2861f45e5ba52cfaa777b6e7fa9aab6c\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"payer\": \"0xd99b1eba9b561cfa\"\n  }\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa28ffffffffffffffffff0148465080c2d72f5801\"\n  }\n}\n```\n\nPass the `options` through to the `/construction/metadata` call:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa28ffffffffffffffffff0148465080c2d72f5801\"\n  }\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"metadata\": {\n    \"height\": \"69453800\",\n    \"protobuf\": \"0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n  },\n  \"suggested_fee\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"100449\"\n    }\n  ]\n}\n```\n\nThen pass that through to the `/construction/payloads` call using the same\n`public_key` as in the `/construction/preprocess` call:\n\n```json\n{\n  \"payloads\": [\n    {\n      \"account_identifier\": {\n        \"address\": \"0xd99b1eba9b561cfa\"\n      },\n      \"address\": \"0xd99b1eba9b561cfa\",\n      \"hex_bytes\": \"e089ac76de893e4aca1d61b2c340f01c6b4de4c724a968c43e4eeda482c9b00f\",\n      \"signature_type\": \"ecdsa\"\n    }\n  ],\n  \"unsigned_transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"payloads\": [\n    {\n      \"account_identifier\": {\n        \"address\": \"0xd99b1eba9b561cfa\"\n      },\n      \"address\": \"0xd99b1eba9b561cfa\",\n      \"hex_bytes\": \"e089ac76de893e4aca1d61b2c340f01c6b4de4c724a968c43e4eeda482c9b00f\",\n      \"signature_type\": \"ecdsa\"\n    }\n  ],\n  \"unsigned_transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n}\n```\n\nTake the `payloads[0].hex_bytes` and sign it using the `payer`'s private key,\ni.e. our root originator. You can use the helper `cmd/sign` tool for this:\n\n```bash\n$ go run cmd/sign/sign.go 914bf493aacd199c1f4f2f19d3f80ef69066307d39d7f4ccfe298ab76fbee0b5 e089ac76de893e4aca1d61b2c340f01c6b4de4c724a968c43e4eeda482c9b00f\nbc688b21f76f2d3704d5c174464bd428be68704413c9f6401c0bf51e9a80e28a6c117dc9b10b9c7818426bcfb5d62919a3b242c8d4c47d10824fc661d64f886a\n```\n\nIt takes two parameters, first is the hex-encoded private key, and the second is\nthe `payload.hex_bytes` value.\n\nNow make a call to `/construction/combine`:\n\n* Copy the `unsigned_transaction` from the `/construction/payloads` response\n\n* Copy `payloads[0]` from the `/construction/payloads` response, and set it as\n  `signatures[0].signing_payload`\n\n* Set the signer address's public key in `signatures[0].public_key.hex_bytes`.\n\n* Copy the hex-encoded signature output from `cmd/sign` output and set it as\n  `signatures[0].hex_bytes`\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"unsigned_transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\",\n  \"signatures\": [\n    {\n      \"signing_payload\": {\n        \"account_identifier\": {\n          \"address\": \"0xd99b1eba9b561cfa\"\n        },\n        \"address\": \"0xd99b1eba9b561cfa\",\n        \"hex_bytes\": \"e089ac76de893e4aca1d61b2c340f01c6b4de4c724a968c43e4eeda482c9b00f\",\n        \"signature_type\": \"ecdsa\"\n      },\n      \"public_key\": {\n        \"hex_bytes\": \"027509387372ee7ded90281fe21dc5b250b609bacc516da473756d7f190ec2bce7\",\n        \"curve_type\": \"secp256k1\"\n      },\n      \"signature_type\": \"ecdsa\",\n      \"hex_bytes\": \"bc688b21f76f2d3704d5c174464bd428be68704413c9f6401c0bf51e9a80e28a6c117dc9b10b9c7818426bcfb5d62919a3b242c8d4c47d10824fc661d64f886a\"\n    }\n  ]\n}\n```\n\nThis will return a response like:\n\n```json\n{\n  \"signed_transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa4a4c0a08d99b1eba9b561cfa1a40bc688b21f76f2d3704d5c174464bd428be68704413c9f6401c0bf51e9a80e28a6c117dc9b10b9c7818426bcfb5d62919a3b242c8d4c47d10824fc661d64f886a:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n}\n```\n\nOptionally validate that the signed transaction matches the original intent by\ncalling `/construction/parse`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"signed\": true,\n  \"transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa4a4c0a08d99b1eba9b561cfa1a40bc688b21f76f2d3704d5c174464bd428be68704413c9f6401c0bf51e9a80e28a6c117dc9b10b9c7818426bcfb5d62919a3b242c8d4c47d10824fc661d64f886a:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n}\n```\n\nThis returns something like:\n\n```json\n{\n  \"account_identifier_signers\": [\n    {\n      \"address\": \"0xd99b1eba9b561cfa\"\n    }\n  ],\n  \"operations\": [\n    {\n      \"metadata\": {\n        \"public_key\": \"02bd7bfdb6297207619eb9907a39f512ac2861f45e5ba52cfaa777b6e7fa9aab6c\"\n      },\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"type\": \"create_account\"\n    }\n  ],\n  \"signers\": [\n    \"0xd99b1eba9b561cfa\"\n  ]\n}\n```\n\nAs we can see, the `operations` match what we specified.\n\nWe can now submit the transaction by calling `/construction/submit`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"signed_transaction\": \"010ab7047472616e73616374696f6e287075626c69634b6579733a205b537472696e675d29207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a2020202020202020666f72206b657920696e207075626c69634b657973207b0a2020202020202020202020202f2f2043726561746520616e206163636f756e7420616e642073657420746865206163636f756e74207075626c6963206b65792e0a2020202020202020202020206c65742061636374203d20417574684163636f756e742870617965723a207061796572290a2020202020202020202020206c6574207075626c69634b6579203d205075626c69634b6579280a202020202020202020202020202020207075626c69634b65793a206b65792e6465636f646548657828292c0a202020202020202020202020202020207369676e6174757265416c676f726974686d3a205369676e6174757265416c676f726974686d2e45434453415f736563703235366b310a202020202020202020202020290a202020202020202020202020616363742e6b6579732e616464280a202020202020202020202020202020207075626c69634b65793a207075626c69634b65792c0a2020202020202020202020202020202068617368416c676f726974686d3a2048617368416c676f726974686d2e534841335f3235362c0a202020202020202020202020202020207765696768743a20313030302e300a202020202020202020202020290a20202020202020207d0a202020207d0a7d0a12b8017b2274797065223a224172726179222c2276616c7565223a5b7b2274797065223a22537472696e67222c2276616c7565223a226264376266646236323937323037363139656239393037613339663531326163323836316634356535626135326366616137373762366537666139616162366334353532326661613031336331343931363237626235333466646263616533663035343539383266366266373762363635626331363265626632353932343834227d5d7d0a1a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb9208f4e2a0d0a08d99b1eba9b561cfa18883f3208d99b1eba9b561cfa3a08d99b1eba9b561cfa4a4c0a08d99b1eba9b561cfa1a40bc688b21f76f2d3704d5c174464bd428be68704413c9f6401c0bf51e9a80e28a6c117dc9b10b9c7818426bcfb5d62919a3b242c8d4c47d10824fc661d64f886a:0a206d71c7a5a0aee59bf54899ed2622cc0ef724baabb20d2f71f4e851937e9a0cb91a08d99b1eba9b561cfa28883f30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040e1900648465080c2d72f5801\"\n}\n```\n\nThis will return something like:\n\n```json\n{\n  \"transaction_identifier\": {\n    \"hash\": \"f0a9f4f2ff38d9049e12312ff6ee2087e0c0e53ea0cf2849579ed72e245ed9ad\"\n  }\n}\n```\n\nYou can then look up the transaction on the Flow Testnet Explorer, e.g.\n\n* https://testnet.flowscan.org/transaction/f0a9f4f2ff38d9049e12312ff6ee2087e0c0e53ea0cf2849579ed72e245ed9ad\n\nThis tells us that account `0x94b6cb63cb81177a` was successfully created by the\ntransaction in block `69454076`.\n\nWe can confirm that Flow Rosetta has indexed the corresponding operation by\ncalling `/block`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"block_identifier\": {\n    \"index\": 69454076\n  }\n}\n```\n\nWhich shows us the corresponding `create_account` operation and its address:\n\n```json\n{\n  \"block\": {\n    \"block_identifier\": {\n      \"hash\": \"858eb2a4e96b7a01f0d6430022c4f5b26a59dc87ce60647e6ef1a74dbfddd234\",\n      \"index\": 69454076\n    },\n    \"parent_block_identifier\": {\n      \"hash\": \"366794281fac18111f84f5a04da44c380e3220d8c1e7fdc070b059d854b955d4\",\n      \"index\": 69454075\n    },\n    \"timestamp\": 1653961701995,\n    \"transactions\": [\n      {\n        \"metadata\": {\n          \"error_message\": \"\",\n          \"events\": [\n            {\n              \"amount\": \"100000\",\n              \"sender\": \"0xd99b1eba9b561cfa\",\n              \"type\": \"WITHDRAWAL\"\n            },\n            {\n              \"amount\": \"100000\",\n              \"type\": \"WITHDRAWAL\"\n            },\n            {\n              \"amount\": \"0\",\n              \"receiver\": \"0x912d5440f7e3769e\",\n              \"type\": \"DEPOSIT\"\n            },\n            {\n              \"amount\": \"100000\",\n              \"receiver\": \"0x94b6cb63cb81177a\",\n              \"type\": \"DEPOSIT\"\n            },\n            {\n              \"amount\": \"314\",\n              \"sender\": \"0xd99b1eba9b561cfa\",\n              \"type\": \"WITHDRAWAL\"\n            },\n            {\n              \"amount\": \"314\",\n              \"receiver\": \"0x912d5440f7e3769e\",\n              \"type\": \"DEPOSIT\"\n            }\n          ],\n          \"failed\": false\n        },\n        \"operations\": [\n          {\n            \"operation_identifier\": {\n              \"index\": 0\n            },\n            \"type\": \"create_account\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0x94b6cb63cb81177a\"\n            }\n          },\n          {\n            \"operation_identifier\": {\n              \"index\": 1\n            },\n            \"type\": \"fee\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0xd99b1eba9b561cfa\"\n            },\n            \"amount\": {\n              \"value\": \"-314\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          },\n          {\n            \"operation_identifier\": {\n              \"index\": 2\n            },\n            \"type\": \"transfer\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0xd99b1eba9b561cfa\"\n            },\n            \"amount\": {\n              \"value\": \"-100000\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          },\n          {\n            \"operation_identifier\": {\n              \"index\": 3\n            },\n            \"related_operations\": [\n              {\n                \"index\": 2\n              }\n            ],\n            \"type\": \"transfer\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0x94b6cb63cb81177a\"\n            },\n            \"amount\": {\n              \"value\": \"100000\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          }\n        ],\n        \"transaction_identifier\": {\n          \"hash\": \"f0a9f4f2ff38d9049e12312ff6ee2087e0c0e53ea0cf2849579ed72e245ed9ad\"\n        }\n      }\n    ]\n  }\n}\n```\n\nTada!\n\n## Creating Proxy Accounts via the Rosetta Construction API\n\nProxy accounts can be created in the exact same way as normal accounts, just use\nthe operation `type` of `create_proxy_account` instead of `create_account`.\n\nFirst, generate a key:\n\n```bash\n$ go run cmd/genkey/genkey.go\nPublic Key (Flow Format): ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b7c1529f9e0e79f7060d09b6ea2bc9d804521406ce0f88996071344a10081ea53\nPublic Key (Rosetta Format): 03ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b\nPrivate Key: 52c354a66d683929847126a27cb7a8b3b63f8d2c69d60bd4ad7867b7c3b95709\n```\n\nIf you then send the following `/construction/preprocess` request:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"create_proxy_account\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"metadata\": {\n        \"public_key\": \"03ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"payer\": \"0xd99b1eba9b561cfa\"\n  }\n}\n```\n\nWill respond with something like:\n\n```json\n{\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa28ffffffffffffffffff01486e5080c2d72f5801\"\n  }\n}\n```\n\nIf we pass it along to `/construction/metadata`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa28ffffffffffffffffff01486e5080c2d72f5801\"\n  }\n}\n```\n\nIt will respond with something like:\n\n```json\n{\n  \"metadata\": {\n    \"height\": \"69243533\",\n    \"protobuf\": \"0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\"\n  },\n  \"suggested_fee\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"100648\"\n    }\n  ]\n}\n```\n\nIf we follow-up with a request to `/construction/payloads`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"create_proxy_account\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"metadata\": {\n        \"public_key\": \"03ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"protobuf\": \"0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\"\n  }\n}\n```\n\nIt will respond with something like:\n\n```json\n{\n  \"payloads\": [\n    {\n      \"account_identifier\": {\n        \"address\": \"0xd99b1eba9b561cfa\"\n      },\n      \"address\": \"0xd99b1eba9b561cfa\",\n      \"hex_bytes\": \"ab3ef346874808566379f0d1104c79192adbcbaaba50f44d3a8ce794f9535215\",\n      \"signature_type\": \"ecdsa\"\n    }\n  ],\n  \"unsigned_transaction\": \"010a9602696d706f727420466c6f77436f6c6453746f7261676550726f78792066726f6d203078303263316461333833363930356362340a0a7472616e73616374696f6e287075626c69634b65793a20537472696e6729207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a20202020202020202f2f204372656174652061206e6577206163636f756e742077697468206120466c6f77436f6c6453746f7261676550726f7879205661756c742e0a2020202020202020466c6f77436f6c6453746f7261676550726f78792e73657475702870617965723a2070617965722c207075626c69634b65793a207075626c69634b65792e6465636f64654865782829290a202020207d0a7d0a129d017b2274797065223a22537472696e67222c2276616c7565223a226163386666656339633362353836396562333138383836353333346337303363666264326561656562636632623333623666336663626436393838363831316237633135323966396530653739663730363064303962366561326263396438303435323134303663653066383839393630373133343461313030383165613533227d0a1a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a208f4e2a0d0a08d99b1eba9b561cfa18cc353208d99b1eba9b561cfa3a08d99b1eba9b561cfa:0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\"\n}\n```\n\nWe can then sign the payload for the unsigned transaction with the private key\nof our root originator:\n\n```bash\n$ go run cmd/sign/sign.go 914bf493aacd199c1f4f2f19d3f80ef69066307d39d7f4ccfe298ab76fbee0b5 ab3ef346874808566379f0d1104c79192adbcbaaba50f44d3a8ce794f9535215\ncddb3e61ce93a094deec2fd3f8d090620836eb3a431b5efef49ac7e1744d03f31c991114f14cc9592686f6a97d18bdb1afd27b2c0697cc3e0b8baad5c2e7b979\n```\n\nAnd pass it along to `/construction/combine`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"unsigned_transaction\": \"010a9602696d706f727420466c6f77436f6c6453746f7261676550726f78792066726f6d203078303263316461333833363930356362340a0a7472616e73616374696f6e287075626c69634b65793a20537472696e6729207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a20202020202020202f2f204372656174652061206e6577206163636f756e742077697468206120466c6f77436f6c6453746f7261676550726f7879205661756c742e0a2020202020202020466c6f77436f6c6453746f7261676550726f78792e73657475702870617965723a2070617965722c207075626c69634b65793a207075626c69634b65792e6465636f64654865782829290a202020207d0a7d0a129d017b2274797065223a22537472696e67222c2276616c7565223a226163386666656339633362353836396562333138383836353333346337303363666264326561656562636632623333623666336663626436393838363831316237633135323966396530653739663730363064303962366561326263396438303435323134303663653066383839393630373133343461313030383165613533227d0a1a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a208f4e2a0d0a08d99b1eba9b561cfa18cc353208d99b1eba9b561cfa3a08d99b1eba9b561cfa:0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\",\n  \"signatures\": [\n    {\n      \"signing_payload\": {\n        \"account_identifier\": {\n          \"address\": \"0xd99b1eba9b561cfa\"\n        },\n        \"address\": \"0xd99b1eba9b561cfa\",\n        \"hex_bytes\": \"ab3ef346874808566379f0d1104c79192adbcbaaba50f44d3a8ce794f9535215\",\n        \"signature_type\": \"ecdsa\"\n      },\n      \"public_key\": {\n        \"hex_bytes\": \"027509387372ee7ded90281fe21dc5b250b609bacc516da473756d7f190ec2bce7\",\n        \"curve_type\": \"secp256k1\"\n      },\n      \"signature_type\": \"ecdsa\",\n      \"hex_bytes\": \"cddb3e61ce93a094deec2fd3f8d090620836eb3a431b5efef49ac7e1744d03f31c991114f14cc9592686f6a97d18bdb1afd27b2c0697cc3e0b8baad5c2e7b979\"\n    }\n  ]\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"signed_transaction\": \"010a9602696d706f727420466c6f77436f6c6453746f7261676550726f78792066726f6d203078303263316461333833363930356362340a0a7472616e73616374696f6e287075626c69634b65793a20537472696e6729207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a20202020202020202f2f204372656174652061206e6577206163636f756e742077697468206120466c6f77436f6c6453746f7261676550726f7879205661756c742e0a2020202020202020466c6f77436f6c6453746f7261676550726f78792e73657475702870617965723a2070617965722c207075626c69634b65793a207075626c69634b65792e6465636f64654865782829290a202020207d0a7d0a129d017b2274797065223a22537472696e67222c2276616c7565223a226163386666656339633362353836396562333138383836353333346337303363666264326561656562636632623333623666336663626436393838363831316237633135323966396530653739663730363064303962366561326263396438303435323134303663653066383839393630373133343461313030383165613533227d0a1a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a208f4e2a0d0a08d99b1eba9b561cfa18cc353208d99b1eba9b561cfa3a08d99b1eba9b561cfa4a4c0a08d99b1eba9b561cfa1a40cddb3e61ce93a094deec2fd3f8d090620836eb3a431b5efef49ac7e1744d03f31c991114f14cc9592686f6a97d18bdb1afd27b2c0697cc3e0b8baad5c2e7b979:0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\"\n}\n```\n\nWhich we can submit via `/construction/submit`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"signed_transaction\": \"010a9602696d706f727420466c6f77436f6c6453746f7261676550726f78792066726f6d203078303263316461333833363930356362340a0a7472616e73616374696f6e287075626c69634b65793a20537472696e6729207b0a20202020707265706172652870617965723a20417574684163636f756e7429207b0a20202020202020202f2f204372656174652061206e6577206163636f756e742077697468206120466c6f77436f6c6453746f7261676550726f7879205661756c742e0a2020202020202020466c6f77436f6c6453746f7261676550726f78792e73657475702870617965723a2070617965722c207075626c69634b65793a207075626c69634b65792e6465636f64654865782829290a202020207d0a7d0a129d017b2274797065223a22537472696e67222c2276616c7565223a226163386666656339633362353836396562333138383836353333346337303363666264326561656562636632623333623666336663626436393838363831316237633135323966396530653739663730363064303962366561326263396438303435323134303663653066383839393630373133343461313030383165613533227d0a1a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a208f4e2a0d0a08d99b1eba9b561cfa18cc353208d99b1eba9b561cfa3a08d99b1eba9b561cfa4a4c0a08d99b1eba9b561cfa1a40cddb3e61ce93a094deec2fd3f8d090620836eb3a431b5efef49ac7e1744d03f31c991114f14cc9592686f6a97d18bdb1afd27b2c0697cc3e0b8baad5c2e7b979:0a209eb08c3774b4f422c6b191658b60cafdf69bceb0f519100169f33a49411b7f8a1a08d99b1eba9b561cfa28cc3530013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040a89206486e5080c2d72f5801\"\n}\n```\n\nResulting in something like:\n\n```json\n{\n  \"transaction_identifier\": {\n    \"hash\": \"ac07e337090e0ae33aa06ece96988cba49ade0294fc459aa5bb5beaf7b221b32\"\n  }\n}\n```\n\nWe can then view the transaction on the Flow Testnet Explorer:\n\n* https://testnet.flowscan.org/transaction/ac07e337090e0ae33aa06ece96988cba49ade0294fc459aa5bb5beaf7b221b32\n\nThis tells us that the transaction in block `69243540` has successfully created\na new account at `0xf5d5bcb3c4e0b071` with a `FlowColdStorageProxy.Vault`.\n\nWe can check that Flow Rosetta has also seen this with a request to `/block`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"block_identifier\": {\n    \"index\": 69243540\n  }\n}\n```\n\nThis confirms the newly created proxy account within the corresponding\ntransaction's `operations`:\n\n```json\n{\n  \"operation_identifier\": {\n    \"index\": 0\n  },\n  \"type\": \"create_proxy_account\",\n  \"status\": \"SUCCESS\",\n  \"account\": {\n    \"address\": \"0xf5d5bcb3c4e0b071\"\n  },\n  \"metadata\": {\n    \"proxy_public_key\": \"03ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b\"\n  }\n}\n```\n\n## Creating Transfers via the Rosetta Construction API\n\nFor the purposes of this example, we will be transferring from the account we\ncreated earlier, `0x94b6cb63cb81177a`, to the proxy account we created,\n`0xf5d5bcb3c4e0b071`.\n\nWe need to first deposit some FLOW into the sender's account so that it actually\nhas some funds to transfer. We will do this using an external account we have,\ne.g.\n\n```bash\n$ flow transactions send  --network testnet --signer test-account \\\n    deposit.cdc 0x94b6cb63cb81177a 2.0\n```\n\nWhere `deposit.cdc` looks like:\n\n```cadence\nimport FlowToken from 0x7e60df042a9c0868\nimport FungibleToken from 0x9a0766d93b6608b7\n\ntransaction(receiver: Address, amount: UFix64) {\n    let xfer: @FungibleToken.Vault\n    prepare(sender: AuthAccount) {\n        let vault = sender.borrow\u003c\u0026FlowToken.Vault\u003e(from: /storage/flowTokenVault)!\n        self.xfer \u003c- vault.withdraw(amount: amount)\n    }\n    execute {\n        let receiver = getAccount(receiver)\n            .capabilities.borrow\u003c\u0026{FungibleToken.Receiver}\u003e(/public/flowTokenReceiver)!\n        receiver.deposit(from: \u003c-self.xfer)\n    }\n}\n```\n\nWe can confirm the updated account balance with a call to `/account/balance`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"account_identifier\": {\n    \"address\": \"0x94b6cb63cb81177a\"\n  }\n}\n```\n\nThat shows us the expected balance of 2.001 FLOW (the 2 FLOW that were deposited\nand the minimum account balance of 0.001 FLOW):\n\n```json\n{\n  \"balances\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"200100000\"\n    }\n  ],\n  \"block_identifier\": {\n    \"hash\": \"9b40d58cc50c5a940034c8084dc6554b936a8febc3abc8c4641a843b88278cf4\",\n    \"index\": 69456516\n  },\n  \"metadata\": {\n    \"sequence_number\": \"0\"\n  }\n}\n```\n\nWe can now make the call to `/construction/preprocess` with the appropriate\nvalues:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"transfer\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"account\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"-50000000\"\n      }\n    },\n    {\n      \"type\": \"transfer\",\n      \"operation_identifier\": {\n        \"index\": 1\n      },\n      \"related_operations\": [\n        {\n          \"index\": 0\n        }\n      ],\n      \"account\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"50000000\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"payer\": \"0x94b6cb63cb81177a\"\n  }\n}\n```\n\nIt will respond with something like:\n\n```json\n{\n  \"options\": {\n    \"protobuf\": \"1a0894b6cb63cb81177a28ffffffffffffffffff0148505080c2d72f\"\n  }\n}\n```\n\nWe can then make the `/construction/metadata` call:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"options\": {\n    \"protobuf\": \"1a0894b6cb63cb81177a28ffffffffffffffffff0148505080c2d72f\"\n  }\n}\n```\n\nWhich will respond with something like:\n\n```json\n{\n  \"metadata\": {\n    \"height\": \"69456819\",\n    \"protobuf\": \"0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\"\n  },\n  \"suggested_fee\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"499\"\n    }\n  ]\n}\n```\n\nThis will give us the info needed to make the `/construction/payloads` call:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"transfer\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"account\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"-50000000\"\n      }\n    },\n    {\n      \"type\": \"transfer\",\n      \"operation_identifier\": {\n        \"index\": 1\n      },\n      \"related_operations\": [\n        {\n          \"index\": 0\n        }\n      ],\n      \"account\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"50000000\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"protobuf\": \"0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\"\n  }\n}\n```\n\nIt will respond with something like:\n\n```json\n{\n  \"payloads\": [\n    {\n      \"account_identifier\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"address\": \"0x94b6cb63cb81177a\",\n      \"hex_bytes\": \"087ea79d95670e78eba5f5d48ccedb4c716fe7dcd1ae71e06e498430be589b82\",\n      \"signature_type\": \"ecdsa\"\n    }\n  ],\n  \"unsigned_transaction\": \"010abc08696d706f727420466c6f77546f6b656e2066726f6d203078376536306466303432613963303836380a696d706f72742046756e6769626c65546f6b656e2066726f6d203078396130373636643933623636303862370a0a7472616e73616374696f6e2872656365697665723a20416464726573732c20616d6f756e743a2055466978363429207b0a0a202020202f2f20546865205661756c74207265736f75726365207468617420686f6c64732074686520746f6b656e73207468617420617265206265696e67207472616e736665727265642e0a202020206c657420786665723a204046756e6769626c65546f6b656e2e5661756c740a0a20202020707265706172652873656e6465723a20417574684163636f756e7429207b0a20202020202020202f2f204765742061207265666572656e636520746f207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a20202020202020206c6574207661756c74203d2073656e6465722e626f72726f773c26466c6f77546f6b656e2e5661756c743e2866726f6d3a202f73746f726167652f666c6f77546f6b656e5661756c74290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652073656e6465722773207661756c7422290a0a20202020202020202f2f20576974686472617720746f6b656e732066726f6d207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a202020202020202073656c662e78666572203c2d207661756c742e776974686472617728616d6f756e743a20616d6f756e74290a202020207d0a0a2020202065786563757465207b0a20202020202020202f2f204765742061207265666572656e636520746f2074686520726563656976657227732064656661756c742046756e6769626c65546f6b656e2e52656365697665720a20202020202020202f2f20666f7220464c4f5720746f6b656e732e0a20202020202020206c6574207265636569766572203d206765744163636f756e74287265636569766572290a2020202020202020202020202e6765744361706162696c697479282f7075626c69632f666c6f77546f6b656e5265636569766572290a2020202020202020202020202e626f72726f773c267b46756e6769626c65546f6b656e2e52656365697665727d3e28290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652072656365697665722773207661756c7422290a0a20202020202020202f2f204465706f736974207468652077697468647261776e20746f6b656e7320696e207468652072656365697665722773207661756c742e0a202020202020202072656365697665722e6465706f7369742866726f6d3a203c2d73656c662e78666572290a202020207d0a7d0a12307b2274797065223a2241646472657373222c2276616c7565223a22307866356435626362336334653062303731227d0a12277b2274797065223a22554669783634222c2276616c7565223a22302e3530303030303030227d0a1a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f208f4e2a0a0a0894b6cb63cb81177a320894b6cb63cb81177a3a0894b6cb63cb81177a:0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\"\n}\n```\n\nWe can then sign the unsigned transaction with the sender's private key:\n\n```bash\n$ go run cmd/sign/sign.go dc915efc3992d2c59b69de4948d565ac953818d9ccee78b65df590764786ada0 087ea79d95670e78eba5f5d48ccedb4c716fe7dcd1ae71e06e498430be589b82\n403412f6b7ca95b6c5500b23cc2119c9083da7094446c24d80337f538913310a7dd1730c58f44587f24bfedc3f60c91e248d3b759097d2f76acb73ba2bfe6e71\n```\n\nAnd make the call to `/construction/combine`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"unsigned_transaction\": \"010abc08696d706f727420466c6f77546f6b656e2066726f6d203078376536306466303432613963303836380a696d706f72742046756e6769626c65546f6b656e2066726f6d203078396130373636643933623636303862370a0a7472616e73616374696f6e2872656365697665723a20416464726573732c20616d6f756e743a2055466978363429207b0a0a202020202f2f20546865205661756c74207265736f75726365207468617420686f6c64732074686520746f6b656e73207468617420617265206265696e67207472616e736665727265642e0a202020206c657420786665723a204046756e6769626c65546f6b656e2e5661756c740a0a20202020707265706172652873656e6465723a20417574684163636f756e7429207b0a20202020202020202f2f204765742061207265666572656e636520746f207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a20202020202020206c6574207661756c74203d2073656e6465722e626f72726f773c26466c6f77546f6b656e2e5661756c743e2866726f6d3a202f73746f726167652f666c6f77546f6b656e5661756c74290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652073656e6465722773207661756c7422290a0a20202020202020202f2f20576974686472617720746f6b656e732066726f6d207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a202020202020202073656c662e78666572203c2d207661756c742e776974686472617728616d6f756e743a20616d6f756e74290a202020207d0a0a2020202065786563757465207b0a20202020202020202f2f204765742061207265666572656e636520746f2074686520726563656976657227732064656661756c742046756e6769626c65546f6b656e2e52656365697665720a20202020202020202f2f20666f7220464c4f5720746f6b656e732e0a20202020202020206c6574207265636569766572203d206765744163636f756e74287265636569766572290a2020202020202020202020202e6765744361706162696c697479282f7075626c69632f666c6f77546f6b656e5265636569766572290a2020202020202020202020202e626f72726f773c267b46756e6769626c65546f6b656e2e52656365697665727d3e28290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652072656365697665722773207661756c7422290a0a20202020202020202f2f204465706f736974207468652077697468647261776e20746f6b656e7320696e207468652072656365697665722773207661756c742e0a202020202020202072656365697665722e6465706f7369742866726f6d3a203c2d73656c662e78666572290a202020207d0a7d0a12307b2274797065223a2241646472657373222c2276616c7565223a22307866356435626362336334653062303731227d0a12277b2274797065223a22554669783634222c2276616c7565223a22302e3530303030303030227d0a1a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f208f4e2a0a0a0894b6cb63cb81177a320894b6cb63cb81177a3a0894b6cb63cb81177a:0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\",\n  \"signatures\": [\n    {\n      \"signing_payload\": {\n        \"account_identifier\": {\n          \"address\": \"0xd99b1eba9b561cfa\"\n        },\n        \"address\": \"0xd99b1eba9b561cfa\",\n        \"hex_bytes\": \"087ea79d95670e78eba5f5d48ccedb4c716fe7dcd1ae71e06e498430be589b82\",\n        \"signature_type\": \"ecdsa\"\n      },\n      \"public_key\": {\n        \"hex_bytes\": \"02bd7bfdb6297207619eb9907a39f512ac2861f45e5ba52cfaa777b6e7fa9aab6c\",\n        \"curve_type\": \"secp256k1\"\n      },\n      \"signature_type\": \"ecdsa\",\n      \"hex_bytes\": \"403412f6b7ca95b6c5500b23cc2119c9083da7094446c24d80337f538913310a7dd1730c58f44587f24bfedc3f60c91e248d3b759097d2f76acb73ba2bfe6e71\"\n    }\n  ]\n}\n```\n\nWhich will respond will something like:\n\n```json\n{\n  \"signed_transaction\": \"010abc08696d706f727420466c6f77546f6b656e2066726f6d203078376536306466303432613963303836380a696d706f72742046756e6769626c65546f6b656e2066726f6d203078396130373636643933623636303862370a0a7472616e73616374696f6e2872656365697665723a20416464726573732c20616d6f756e743a2055466978363429207b0a0a202020202f2f20546865205661756c74207265736f75726365207468617420686f6c64732074686520746f6b656e73207468617420617265206265696e67207472616e736665727265642e0a202020206c657420786665723a204046756e6769626c65546f6b656e2e5661756c740a0a20202020707265706172652873656e6465723a20417574684163636f756e7429207b0a20202020202020202f2f204765742061207265666572656e636520746f207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a20202020202020206c6574207661756c74203d2073656e6465722e626f72726f773c26466c6f77546f6b656e2e5661756c743e2866726f6d3a202f73746f726167652f666c6f77546f6b656e5661756c74290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652073656e6465722773207661756c7422290a0a20202020202020202f2f20576974686472617720746f6b656e732066726f6d207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a202020202020202073656c662e78666572203c2d207661756c742e776974686472617728616d6f756e743a20616d6f756e74290a202020207d0a0a2020202065786563757465207b0a20202020202020202f2f204765742061207265666572656e636520746f2074686520726563656976657227732064656661756c742046756e6769626c65546f6b656e2e52656365697665720a20202020202020202f2f20666f7220464c4f5720746f6b656e732e0a20202020202020206c6574207265636569766572203d206765744163636f756e74287265636569766572290a2020202020202020202020202e6765744361706162696c697479282f7075626c69632f666c6f77546f6b656e5265636569766572290a2020202020202020202020202e626f72726f773c267b46756e6769626c65546f6b656e2e52656365697665727d3e28290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652072656365697665722773207661756c7422290a0a20202020202020202f2f204465706f736974207468652077697468647261776e20746f6b656e7320696e207468652072656365697665722773207661756c742e0a202020202020202072656365697665722e6465706f7369742866726f6d3a203c2d73656c662e78666572290a202020207d0a7d0a12307b2274797065223a2241646472657373222c2276616c7565223a22307866356435626362336334653062303731227d0a12277b2274797065223a22554669783634222c2276616c7565223a22302e3530303030303030227d0a1a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f208f4e2a0a0a0894b6cb63cb81177a320894b6cb63cb81177a3a0894b6cb63cb81177a4a4c0a0894b6cb63cb81177a1a40403412f6b7ca95b6c5500b23cc2119c9083da7094446c24d80337f538913310a7dd1730c58f44587f24bfedc3f60c91e248d3b759097d2f76acb73ba2bfe6e71:0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\"\n}\n```\n\nAnd, finally, submit the transaction via `/construction/submit`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"signed_transaction\": \"010abc08696d706f727420466c6f77546f6b656e2066726f6d203078376536306466303432613963303836380a696d706f72742046756e6769626c65546f6b656e2066726f6d203078396130373636643933623636303862370a0a7472616e73616374696f6e2872656365697665723a20416464726573732c20616d6f756e743a2055466978363429207b0a0a202020202f2f20546865205661756c74207265736f75726365207468617420686f6c64732074686520746f6b656e73207468617420617265206265696e67207472616e736665727265642e0a202020206c657420786665723a204046756e6769626c65546f6b656e2e5661756c740a0a20202020707265706172652873656e6465723a20417574684163636f756e7429207b0a20202020202020202f2f204765742061207265666572656e636520746f207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a20202020202020206c6574207661756c74203d2073656e6465722e626f72726f773c26466c6f77546f6b656e2e5661756c743e2866726f6d3a202f73746f726167652f666c6f77546f6b656e5661756c74290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652073656e6465722773207661756c7422290a0a20202020202020202f2f20576974686472617720746f6b656e732066726f6d207468652073656e646572277320466c6f77546f6b656e2e5661756c742e0a202020202020202073656c662e78666572203c2d207661756c742e776974686472617728616d6f756e743a20616d6f756e74290a202020207d0a0a2020202065786563757465207b0a20202020202020202f2f204765742061207265666572656e636520746f2074686520726563656976657227732064656661756c742046756e6769626c65546f6b656e2e52656365697665720a20202020202020202f2f20666f7220464c4f5720746f6b656e732e0a20202020202020206c6574207265636569766572203d206765744163636f756e74287265636569766572290a2020202020202020202020202e6765744361706162696c697479282f7075626c69632f666c6f77546f6b656e5265636569766572290a2020202020202020202020202e626f72726f773c267b46756e6769626c65546f6b656e2e52656365697665727d3e28290a2020202020202020202020203f3f2070616e69632822436f756c64206e6f7420626f72726f772061207265666572656e636520746f207468652072656365697665722773207661756c7422290a0a20202020202020202f2f204465706f736974207468652077697468647261776e20746f6b656e7320696e207468652072656365697665722773207661756c742e0a202020202020202072656365697665722e6465706f7369742866726f6d3a203c2d73656c662e78666572290a202020207d0a7d0a12307b2274797065223a2241646472657373222c2276616c7565223a22307866356435626362336334653062303731227d0a12277b2274797065223a22554669783634222c2276616c7565223a22302e3530303030303030227d0a1a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f208f4e2a0a0a0894b6cb63cb81177a320894b6cb63cb81177a3a0894b6cb63cb81177a4a4c0a0894b6cb63cb81177a1a40403412f6b7ca95b6c5500b23cc2119c9083da7094446c24d80337f538913310a7dd1730c58f44587f24bfedc3f60c91e248d3b759097d2f76acb73ba2bfe6e71:0a206649ceb829aa82d72133888d190633d1200fb2abbdb2476b46542b9aee152a4f1a0894b6cb63cb81177a30013a236163636573732e6465766e65742e6e6f6465732e6f6e666c6f772e6f72673a3930303040f30348505080c2d72f\"\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"transaction_identifier\": {\n    \"hash\": \"5d1979d943fa364b23d11380ab72a2cc49177c3985cc36ded98e26a179b38c80\"\n  }\n}\n```\n\nWe can then view the transaction on the Flow Testnet Explorer:\n\n* https://testnet.flowscan.org/transaction/5d1979d943fa364b23d11380ab72a2cc49177c3985cc36ded98e26a179b38c80\n\nThis tells us that the transaction in block `69456946` has successfully\ntransferred 0.5 FLOW from `0x94b6cb63cb81177a` to `0xf5d5bcb3c4e0b071`.\n\nWe can check that Flow Rosetta has also seen this with a request to `/block`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"block_identifier\": {\n    \"index\": 69456946\n  }\n}\n```\n\nThis lets us confirm the `transfer` operations:\n\n```json\n{\n  \"block\": {\n    \"block_identifier\": {\n      \"hash\": \"1c0c0cb257ee7751f1d86302ec33f2ce8f7d7185881e9c69e768abae11a59e76\",\n      \"index\": 69456946\n    },\n    \"parent_block_identifier\": {\n      \"hash\": \"f40bc5cc1f603647fea4139305a4f81a522a13631e25ef804da2f4b82528867c\",\n      \"index\": 69456945\n    },\n    \"timestamp\": 1653965548661,\n    \"transactions\": [\n      {\n        \"metadata\": {\n          \"error_message\": \"\",\n          \"events\": [\n            {\n              \"amount\": \"50000000\",\n              \"receiver\": \"0xf5d5bcb3c4e0b071\",\n              \"type\": \"PROXY_DEPOSIT\"\n            },\n            {\n              \"amount\": \"50000000\",\n              \"sender\": \"0x94b6cb63cb81177a\",\n              \"type\": \"WITHDRAWAL\"\n            },\n            {\n              \"amount\": \"50000000\",\n              \"receiver\": \"0xf5d5bcb3c4e0b071\",\n              \"type\": \"DEPOSIT\"\n            },\n            {\n              \"amount\": \"209\",\n              \"sender\": \"0x94b6cb63cb81177a\",\n              \"type\": \"WITHDRAWAL\"\n            },\n            {\n              \"amount\": \"209\",\n              \"receiver\": \"0x912d5440f7e3769e\",\n              \"type\": \"DEPOSIT\"\n            }\n          ],\n          \"failed\": false\n        },\n        \"operations\": [\n          {\n            \"operation_identifier\": {\n              \"index\": 0\n            },\n            \"type\": \"fee\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0x94b6cb63cb81177a\"\n            },\n            \"amount\": {\n              \"value\": \"-209\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          },\n          {\n            \"operation_identifier\": {\n              \"index\": 1\n            },\n            \"type\": \"transfer\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0x94b6cb63cb81177a\"\n            },\n            \"amount\": {\n              \"value\": \"-50000000\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          },\n          {\n            \"operation_identifier\": {\n              \"index\": 2\n            },\n            \"related_operations\": [\n              {\n                \"index\": 1\n              }\n            ],\n            \"type\": \"transfer\",\n            \"status\": \"SUCCESS\",\n            \"account\": {\n              \"address\": \"0xf5d5bcb3c4e0b071\"\n            },\n            \"amount\": {\n              \"value\": \"50000000\",\n              \"currency\": {\n                \"symbol\": \"FLOW\",\n                \"decimals\": 8\n              }\n            }\n          }\n        ],\n        \"transaction_identifier\": {\n          \"hash\": \"5d1979d943fa364b23d11380ab72a2cc49177c3985cc36ded98e26a179b38c80\"\n        }\n      }\n    ]\n  }\n}\n```\n\nWe can also make a call to `/account/balance` for the sender account:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"account_identifier\": {\n    \"address\": \"0x94b6cb63cb81177a\"\n  }\n}\n```\n\nThis confirms that its balance has gone down by 0.5 FLOW + fees:\n\n```json\n{\n  \"balances\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"150099791\"\n    }\n  ],\n  \"block_identifier\": {\n    \"hash\": \"51140d4ffa5da144b6348f964a7506baf2132f94b067f0b669f3328e7cb0e5f2\",\n    \"index\": 69457118\n  },\n  \"metadata\": {\n    \"sequence_number\": \"1\"\n  }\n}\n```\n\nAnd a similar `/account/balance` call for the receiver account\n`0xf5d5bcb3c4e0b071` shows that it now has a balance of 0.5 FLOW:\n\n```json\n{\n  \"balances\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"50000000\"\n    }\n  ],\n  \"block_identifier\": {\n    \"hash\": \"65690d19f1d4986cba735193bec25ed709c0b6016b3fcb0d7b500f5ac547d7c3\",\n    \"index\": 69457180\n  },\n  \"metadata\": {\n    \"sequence_number\": \"0\"\n  }\n}\n```\n\n## Creating Proxy Transfers via the Rosetta Construction API\n\nFor the purposes of this example, we will be transferring 0.1 FLOW from the\nproxy account `0xf5d5bcb3c4e0b071` back to `0x94b6cb63cb81177a`, and have the\ntransaction submitted and paid for by our root originator `0xd99b1eba9b561cfa`.\n\nNote: We could have the transaction submitted and paid for by any account. We're\njust using the root originator in this example as it's an account we control\nwhich has some funds.\n\nTo do this, we first call `/construction/preprocess` with an operation type of\n`proxy_transfer_inner` in order to construct the \"inner transaction\":\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"proxy_transfer_inner\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"account\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"-10000000\"\n      }\n    },\n    {\n      \"type\": \"proxy_transfer_inner\",\n      \"operation_identifier\": {\n        \"index\": 1\n      },\n      \"related_operations\": [\n        {\n          \"index\": 0\n        }\n      ],\n      \"account\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"10000000\"\n      }\n    }\n  ]\n}\n```\n\nThis will return with something like:\n\n```json\n{\n  \"options\": {\n    \"protobuf\": \"10011a08f5d5bcb3c4e0b07128ffffffffffffffffff0148505080c2d72f\"\n  }\n}\n```\n\nWe can then pass that along to `/construction/metadata`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"options\": {\n    \"protobuf\": \"10011a08f5d5bcb3c4e0b07128ffffffffffffffffff0148505080c2d72f\"\n  }\n}\n```\n\nWhich will return something like:\n\n```json\n{\n  \"metadata\": {\n    \"height\": \"0\",\n    \"protobuf\": \"10011a08f5d5bcb3c4e0b07148505080c2d72f\"\n  },\n  \"suggested_fee\": [\n    {\n      \"currency\": {\n        \"decimals\": 8,\n        \"symbol\": \"FLOW\"\n      },\n      \"value\": \"0\"\n    }\n  ]\n}\n```\n\nWe can use that to have `/construction/payloads` generate the unsigned\ntransaction:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"proxy_transfer_inner\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"account\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"-10000000\"\n      }\n    },\n    {\n      \"type\": \"proxy_transfer_inner\",\n      \"operation_identifier\": {\n        \"index\": 1\n      },\n      \"related_operations\": [\n        {\n          \"index\": 0\n        }\n      ],\n      \"account\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"10000000\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"protobuf\": \"10011a08f5d5bcb3c4e0b07148505080c2d72f\"\n  }\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"payloads\": [\n    {\n      \"account_identifier\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"address\": \"0xf5d5bcb3c4e0b071\",\n      \"hex_bytes\": \"6639db7fe430364dc85ebd0ed5cd0d2ab7ee2b0e2ed3aa54a409e140ad79abad\",\n      \"signature_type\": \"ecdsa\"\n    }\n  ],\n  \"unsigned_transaction\": \"020000000000989680000000000000000094b6cb63cb81177af5d5bcb3c4e0b071\"\n}\n```\n\nWe can then sign this unsigned \"inner transaction\" with the private key\nassociated with the proxy account:\n\n```bash\n$ go run cmd/sign/sign.go 52c354a66d683929847126a27cb7a8b3b63f8d2c69d60bd4ad7867b7c3b95709 6639db7fe430364dc85ebd0ed5cd0d2ab7ee2b0e2ed3aa54a409e140ad79abad\n7ef5c6f4454c3a2fa1501a7ab6609e5df6f4d3111cf80a14090df86f2d574b212cdb324a3db194b7237110339e3b2edd4a95dd704e9fa63ae15fd29b90e7f8d4\n```\n\nWe then make the `/construction/combine` call:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"unsigned_transaction\": \"020000000000989680000000000000000094b6cb63cb81177af5d5bcb3c4e0b071\",\n  \"signatures\": [\n    {\n      \"signing_payload\": {\n        \"account_identifier\": {\n          \"address\": \"0xf5d5bcb3c4e0b071\"\n        },\n        \"address\": \"0xf5d5bcb3c4e0b071\",\n        \"hex_bytes\": \"6639db7fe430364dc85ebd0ed5cd0d2ab7ee2b0e2ed3aa54a409e140ad79abad\",\n        \"signature_type\": \"ecdsa\"\n      },\n      \"public_key\": {\n        \"hex_bytes\": \"03ac8ffec9c3b5869eb3188865334c703cfbd2eaeebcf2b33b6f3fcbd69886811b\",\n        \"curve_type\": \"secp256k1\"\n      },\n      \"signature_type\": \"ecdsa\",\n      \"hex_bytes\": \"7ef5c6f4454c3a2fa1501a7ab6609e5df6f4d3111cf80a14090df86f2d574b212cdb324a3db194b7237110339e3b2edd4a95dd704e9fa63ae15fd29b90e7f8d4\"\n    }\n  ]\n}\n```\n\nWhich will respond with something like:\n\n```json\n{\n  \"signed_transaction\": \"020000000000989680000000000000000094b6cb63cb81177af5d5bcb3c4e0b0717ef5c6f4454c3a2fa1501a7ab6609e5df6f4d3111cf80a14090df86f2d574b212cdb324a3db194b7237110339e3b2edd4a95dd704e9fa63ae15fd29b90e7f8d4\"\n}\n```\n\nAt this point, we have a signed \"inner transaction\". Unlike the standard Rosetta\ntransaction construction flow, we do not submit this transaction, but instead\nuse the signed transaction as `metadata.proxy_transfer_payload` in the\n`/construction/preprocess` call for the \"outer transaction\" construction.\n\nWe use the `proxy_transfer` operation type for the `/construction/preprocess`\ncall for the \"outer transaction\", and set the `payer` to the address of the\naccount that will simply be paying for the transaction — in this case, our root\noriginator:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"operations\": [\n    {\n      \"type\": \"proxy_transfer\",\n      \"operation_identifier\": {\n        \"index\": 0\n      },\n      \"account\": {\n        \"address\": \"0xf5d5bcb3c4e0b071\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"-10000000\"\n      }\n    },\n    {\n      \"type\": \"proxy_transfer\",\n      \"operation_identifier\": {\n        \"index\": 1\n      },\n      \"related_operations\": [\n        {\n          \"index\": 0\n        }\n      ],\n      \"account\": {\n        \"address\": \"0x94b6cb63cb81177a\"\n      },\n      \"amount\": {\n        \"currency\": {\n          \"decimals\": 8,\n          \"symbol\": \"FLOW\"\n        },\n        \"value\": \"10000000\"\n      }\n    }\n  ],\n  \"metadata\": {\n    \"payer\": \"0xd99b1eba9b561cfa\",\n    \"proxy_transfer_payload\": \"020000000000989680000000000000000094b6cb63cb81177af5d5bcb3c4e0b0717ef5c6f4454c3a2fa1501a7ab6609e5df6f4d3111cf80a14090df86f2d574b212cdb324a3db194b7237110339e3b2edd4a95dd704e9fa63ae15fd29b90e7f8d4\"\n  }\n}\n```\n\nThis will respond with something like:\n\n```json\n{\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa22c201303230303030303030303030393839363830303030303030303030303030303030303934623663623633636238313137376166356435626362336334653062303731376566356336663434353463336132666131353031613761623636303965356466366634643331313163663830613134303930646638366632643537346232313263646233323461336462313934623732333731313033333965336232656464346139356464373034653966613633616531356664323962393065376638643428ffffffffffffffffff01481e5080c2d72f\"\n  }\n}\n```\n\nWe pass that along to `/construction/metadata`:\n\n```json\n{\n  \"network_identifier\": {\n    \"blockchain\": \"flow\",\n    \"network\": \"testnet\"\n  },\n  \"options\": {\n    \"protobuf\": \"1a08d99b1eba9b561cfa22c201303230303030303030303030393839363830303030303030303030303030303030303934623663623633636238313137376166356435626362336334653062303731376566356336663434353463336132666131353031613761623636303965356466366634643331313163663830613134303930646638366632643537346232313263646233323461336462313934623732333731313033333965336232656464346139356464373034653966613633616531356664323962393065376638643428ffffffffffffffffff01481e5080c2d72f\"\n  }\n}\n```\n\nWhich will respond with something like:\n\n```json\n{\n  \"metadata\": {\n    \"height\": \"69490255\",\n    \"protobuf\": \"0a205ed29244aace03b49013da0e763d5c7187ca0cfd7799b6d2d2bae3085935af331a08d99b1eba9b561cfa22c201303230303030303030303030393839363830303030303030303030303030303030303934623663623633636238313137376166356435626362336334653062303731376566356336663434353463336","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Frosetta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonflow%2Frosetta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Frosetta/lists"}