{"id":18308696,"url":"https://github.com/ardriveapp/ardrive-cli","last_synced_at":"2025-04-04T16:09:40.305Z","repository":{"id":37790280,"uuid":"292709647","full_name":"ardriveapp/ardrive-cli","owner":"ardriveapp","description":"The ArDrive Command Line Interface (CLI) is a Node.js application for terminal-based ArDrive workflows. It also offers utility operations for securely interacting with Arweave wallets and inspecting various Arweave blockchain conditions.","archived":false,"fork":false,"pushed_at":"2024-11-22T11:27:32.000Z","size":293787,"stargazers_count":85,"open_issues_count":9,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-20T09:42:48.139Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/ardriveapp.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-04T00:29:34.000Z","updated_at":"2025-03-07T16:19:32.000Z","dependencies_parsed_at":"2023-01-29T15:46:00.696Z","dependency_job_id":"499a9551-1fa9-4845-b665-9c7928b80257","html_url":"https://github.com/ardriveapp/ardrive-cli","commit_stats":{"total_commits":1612,"total_committers":15,"mean_commits":"107.46666666666667","dds":0.5992555831265509,"last_synced_commit":"ac6e8aaaddb563ab55fe01f81ed32b723d4ce79b"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardriveapp%2Fardrive-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardriveapp%2Fardrive-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardriveapp%2Fardrive-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ardriveapp%2Fardrive-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ardriveapp","download_url":"https://codeload.github.com/ardriveapp/ardrive-cli/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246049630,"owners_count":20715511,"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":[],"created_at":"2024-11-05T16:08:58.591Z","updated_at":"2025-03-28T15:05:44.844Z","avatar_url":"https://github.com/ardriveapp.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ardrive-cli\n\nThe _ArDrive Command Line Interface (CLI)_ is a Node.js application for terminal-based [ArDrive] workflows. It also offers utility operations for securely interacting with Arweave wallets and inspecting various [Arweave] blockchain conditions.\n\nCreate your first drive and permanently store your first file on the permaweb with a series of simple CLI commands like so:\n\n```shell\nardrive create-drive --wallet-file /path/to/my/wallet.json --drive-name \"Teenage Love Poetry\"\n{\n    \"created\": [\n        {\n            \"type\": \"drive\",\n            \"metadataTxId\": \"giv2R8Xj0bbe6l5taBTQJk_38zwIrMH_g1-knSCisjU\",\n            \"entityId\": \"898687ea-b678-4f86-b4e7-49560b190356\",\n            \"bundledIn\": \"Vj2x4IBEAezBvhj5RgtA247W_q3S10suI6l0E30GPoE\",\n            \"entityName\": \"Teenage Love Poetry\"\n        },\n        {\n            \"type\": \"folder\",\n            \"metadataTxId\": \"VljnttwUxRStnVuPYakF9e2whjhYJVWB0nSxD5dVyJ8\",\n            \"entityId\": \"f0c58c11-430c-4383-8e54-4d864cc7e927\",\n            \"bundledIn\": \"Vj2x4IBEAezBvhj5RgtA247W_q3S10suI6l0E30GPoE\",\n            \"entityName\": \"Teenage Love Poetry\"\n        },\n        {\n            \"type\": \"bundle\",\n            \"bundleTxId\": \"Vj2x4IBEAezBvhj5RgtA247W_q3S10suI6l0E30GPoE\"\n        }\n    ],\n    \"tips\": [],\n    \"fees\": {\n        \"Vj2x4IBEAezBvhj5RgtA247W_q3S10suI6l0E30GPoE\": \"44579472\"\n    }\n}\n\nardrive upload-file --wallet-file /path/to/my/wallet.json --parent-folder-id \"f0c58c11-430c-4383-8e54-4d864cc7e927\" --local-path ./helloworld.txt --dest-file-name \"ode_to_ardrive.txt\"\n{\n    \"created\": [\n        {\n            \"type\": \"file\",\n            \"entityName\": \"ode_to_ardrive.txt\",\n            \"entityId\": \"bd2ce978-6ede-4b0d-8f79-2d7bc235a0e0\",\n            \"dataTxId\": \"tSMcfvAQu_tKLUkdvRRbqdX93oAf3h6c9eJsSj8mXL4\",\n            \"metadataTxId\": \"EvE06MmE9IKeUzFMnxSgY1M5tJX4uHU64-n8Pf_lZfU\",\n            \"bundledIn\": \"qjdHiQoWlSjCvhj5RgtA247W_q3S10suI6l0E30GPoE\",\n            \"sourceUri\": \"file://Users/BestArDriver/Uploads/helloworld.txt\"\n        },\n        {\n            \"type\": \"bundle\",\n            \"bundleTxId\": \"qjdHiQoWlSjCvhj5RgtA247W_q3S10suI6l0E30GPoE\"\n        }\n    ],\n    \"tips\": [\n        {\n            \"txId\": \"qjdHiQoWlSjCvhj5RgtA247W_q3S10suI6l0E30GPoE\",\n            \"recipient\": {\n                \"address\": \"i325n3L2UvgcavEM8UnFfY0OWBiyf2RrbNsLStPI73o\"\n            },\n            \"winston\": \"10000000\"\n        }\n    ],\n    \"fees\": {\n        \"qjdHiQoWlSjCvhj5RgtA247W_q3S10suI6l0E30GPoE\": 44579472\n    }\n}\n```\n\n**This project is in a state of active development. Use at your own risk!**\n\n# Table of Contents\n\n1. [ArDrive](#ardrive)\n    1. [ArFS](#arfs)\n    2. [Data Portability](#data-portability)\n    3. [Intended Audience](#intended-audience)\n2. [Getting Started](#getting-started)\n    1. [Prerequisites](#prerequisites)\n        1. [Git](#git)\n        2. [NVM (Optional - Recommended)](#nvm)\n    2. [Quick Start](#quick-start)\n        1. [Installing and Starting the CLI From NPM Package](#install-from-npm)\n        2. [Upgrading to the Latest CLI Version](#upgrading)\n    3. [Build and Run from Source](#build-from-source)\n        1. [Install Yarn 3](#yarn3)\n        2. [Husky (Developers Only)](#husky)\n        3. [Using a custom ArDrive-Core-JS (Optional)](#custom-ardrive-core-js)\n        4. [Installing and Starting the CLI From Source](#install-from-src)\n        5. [Recommended Visual Studio Code extensions (Developers Only)](#vs-extensions)\n    4. [Limitations](#limitations)\n3. [Using the CLI](#using-the-cli)\n    1. [CLI Help](#cli-help)\n    2. [CLI Version](#cli-version)\n    3. [Wallet Operations](#wallet-operations)\n    4. [Working With Entities](#working-with-entities)\n        1. [Dry Run](#dry-run)\n        2. [Uploading to Turbo (BETA)](#upload-to-turbo)\n    5. [Working With Drives](#working-with-drives)\n        1. [Understanding Drive Hierarchies](#understanding-drive-hierarchies)\n            1. [Fetching Drive Info](#drive-info)\n        2. [Understanding Drive and File Keys](#understanding-drive-and-file-keys)\n            1. [Derive a Drive Key](#derive-drive-key)\n            2. [Derive a File Key](#derive-file-key)\n        3. [Managing Drive Passwords](#managing-drive-passwords)\n            1. [Supplying Your Password: Environment Variable](#pw-environment-variable)\n            2. [Supplying Your Password: STDIN](#pw-stdin)\n            3. [Supplying Your Password: Prompt](#pw-prompt)\n        4. [Creating Drives](#creating-drives)\n        5. [Listing Drives for an Address](#listing-drives-for-an-address)\n        6. [Listing Every Entity in a Drive](#list-drive)\n        7. [List Drive Pipeline Examples](#list-drive-pipeline-examples)\n            1. [Get Share Links for Files in the Drive](#get-share-links)\n            2. [Get Total Size of Files in the Drive](#get-total-size)\n            3. [Get Total Count of Files in the Drive](#get-file-count)\n    6. [Working With Folders](#working-with-folders)\n        1. [Creating Folders](#creating-folders)\n        2. [Moving Folders](#moving-folders)\n        3. [Renaming Folders](#rename-folder)\n        4. [Viewing Folder Metadata](#viewing-folder-metadata)\n        5. [Listing Contents of a Folder](#listing-contents-of-a-folder)\n    7. [Working With Files](#working-with-files)\n        1. [Uploading a Single File](#uploading-a-single-file)\n        2. [Download a Single File (BETA)](#download-file)\n        3. [Rename a Single File](#rename-file)\n        4. [Uploading a Folder with Files](#bulk-upload)\n        5. [Progress Logging of Transaction Uploads](#progress-logging-of-transaction-uploads)\n        6. [Downloading a Folder with Files](#download-folder)\n        7. [Downloading a Drive](#download-drive)\n        8. [Uploading Multiple Files](#multi-file-upload)\n        9. [Name Conflict Resolution on Upload](#conflict-resolution)\n        10. [Understanding Bundled Transactions](#bundles)\n        11. [Uploading a Non-Bundled Transaction](#no-bundle)\n        12. [Fetching the Metadata of a File Entity](#fetching-the-metadata-of-a-file-entity)\n        13. [Retrying a Failed File Data Transaction (Public Unbundled Files Only)](#retry-tx)\n        14. [Moving Files](#moving-files)\n        15. [Uploading Manifests](#uploading-manifests)\n        16. [Hosting a Webpage with Manifest](#hosting-a-webpage-with-manifest)\n        17. [Uploading With a Custom Content Type](#custom-content-type)\n        18. [Uploading From a Remote URL](#remote-path)\n        19. [Uploading a Custom Manifest](#custom-manifest)\n        20. [Uploading Files with Custom MetaData](#uploading-files-with-custom-metadata)\n        21. [Applying Unique Custom MetaData During Bulk Workflows](#applying-unique-custom-metadata-during-bulk-workflows)\n    8. [Other Utility Operations](#other-utility-operations)\n        1. [Monitoring Transactions](#monitoring-transactions)\n        2. [Dealing With Network Congestion](#dealing-with-network-congestion)\n        3. [Check for network congestion before uploading](#check-congestion)\n        4. [Front-run Congestion By Boosting Miner Rewards](#boost)\n        5. [Send AR Transactions From a Cold Wallet](#cold-tx)\n        6. [Using a Custom Arweave Gateway](#using-a-custom-arweave-gateway)\n        7. [Persistent Caching of ArFS Entity Metadata](#metadata-caching)\n4. [All ArDrive CLI Commands](#all-ardrive-cli-commands)\n5. [Getting Help](#getting-help)\n\n# ArDrive\n\n[ArDrive] is a permanent storage platform whose [applications and core libraries][ardrive-github] offer hierarchical organization, privacy via complete end-to-end encryption, flexibility, extensibility, and access control over your most valuable data, all made possible by its innovative core technology, the [Arweave File System (ArFS) Protocol][arfs].\n\n## ArFS\n\n[ArFS] is a data modeling, storage, and retrieval protocol designed to emulate common file system operations and to provide aspects of mutability to your data hierarchy on [Arweave]'s otherwise permanent, immutable data storage blockweave.\n\n## Data Portability\n\nData uploaded via the ArDrive CLI, once indexed by Arweave's Gateways and sufficiently seeded across enough nodes on the network, can be accessed via all other ArDrive applications including the [ArDrive Web application][ardrive-web-app] at https://app.ardrive.io.\n\nAll transactions successfully executed by ArDrive can always be inspected in the [Viewblock blockchain explorer].\n\n## Intended Audience\n\nThis tool is intended for use by:\n\n\u003cul\u003e\n\u003cli\u003eArDrive power users with advanced workflows and resource efficiency in mind: bulk uploaders, those with larger storage demand, game developers, nft creators, storage/db admins, etc.\u003c/li\u003e\n\u003cli\u003eAutomation tools\u003c/li\u003e\n\u003cli\u003eServices\u003c/li\u003e\n\u003cli\u003eTerminal aficionados\u003c/li\u003e\n\u003cli\u003eExtant and aspiring cypherpunks\u003c/li\u003e\n\u003c/ul\u003e\n\nFor deeper integrations with the [ArDrive] platform, consider using the [ArDrive Core][ardrive-core] (Node) library's configurable and intuitive class interfaces directly within your application.\n\n# Getting Started\n\nTo simply install the latest version of the CLI to your local system and get started, follow the [Quick Start](#quick-start) instructions. To build and/or develop the CLI from source, follow the [Build and Run from Source](#build-from-source) instructions. In either case, be sure to satisfy the requirements in the [Prerequisites](#prerequisites) section.\n\n## Prerequisites\n\nThe following tools must be installed whether performing a [Quick Start](#quick-start) or [Building from Source](#build-from-source):\n\n### Git\n\nSome of ArDrive's dependencies are transitively installed via Git. Install it, if necessary, and ensure that it's available within your terminal environment:\n\n[Download Git](https://git-scm.com/downloads)\n\n### NVM (Optional - Recommended)\u003ca id=\"nvm\"\u003e\u003c/a\u003e\n\nThis project uses the Node Version Manager (NVM) and an `.nvmrc` file to lock the recommended Node version used by the latest version of `ardrive-core-js`.\n\n**Note for Windows: We recommend using WSL for setting up NVM on Windows using the [instructions described here][wsl-install]**\n\nFollow these steps to get NVM up and running on your system:\n\n1. Install NVM using [these installation instructions][nvm-install].\n2. Navigate to this project's root directory\n3. Ensure that the correct version of Node is installed by performing: `nvm install`\n4. Use the correct version of Node, by performing: `nvm use`\n\n**IT IS STRONGLY RECOMMENDED THAT YOU AVOID GENERATING WALLETS VIA SEED PHRASE WITH THE CLI USING ANY NODE VERSION OTHER THAN THE ONE SPECIFIED IN `.nvmrc`.**\n\n## Quick Start\n\nOnce you've satisfied any necessary [prerequisites](#prerequisites), the fastest way to get up and running is to globally install the latest version of the ArDrive CLI to your local system via NPM:\n\n### Installing and Starting the CLI From NPM Package\u003ca id=\"install-from-npm\"\u003e\u003c/a\u003e\n\n```shell\nnpm install -g ardrive-cli\n\n# then invoke the CLI from anywhere on your system:\nardrive\n```\n\n### Upgrading to the Latest Version\u003ca id=\"upgrading\"\u003e\u003c/a\u003e\n\nIf you globally installed the CLI via NPM, then upgrade to the latest version by simply performing:\n\n```shell\nnpm update -g ardrive-cli\n```\n\n## Build and Run from Source\u003ca id=\"build-from-source\"\u003e\u003c/a\u003e\n\n### Install Yarn 3\u003ca id=\"yarn3\"\u003e\u003c/a\u003e\n\nBoth the ArDrive CLI and ArDrive Core JS use Yarn 3 to manage dependencies and initiate workflows, so follow the [yarn installation instructions][yarn-install] in order to get the latest version. In most cases:\n\n```shell\n# Brew (OSX):\nbrew install yarn\n\n# Or with NPM (all supported platforms):\nnpm install -g yarn\n```\n\n### Husky (Developers Only)\u003ca id=\"husky\"\u003e\u003c/a\u003e\n\nWe use husky 6.x to manage the git commit hooks that help to improve the quality of our commits. Please run:\n\n```shell\nyarn husky install\n```\n\nto enable git hooks for your local checkout. Without doing so, you risk committing non-compliant code to the repository.\n\n### Using a custom ArDrive-Core-JS (Optional)\u003ca id=\"custom-ardrive-core-js\"\u003e\u003c/a\u003e\n\nTo test a with a custom version of the `ardrive-core-js` library on your local system, change the `\"ardrive-core-js\"` line in `package.json` to the root of your local `ardrive-core-js` repo:\n\n```diff\n- \"ardrive-core-js\": \"1.0.0\"\n+ \"ardrive-core-js\": \"../ardrive-core-js/\"\n```\n\n### Installing and Starting the CLI From Source\u003ca id=\"install-from-src\"\u003e\u003c/a\u003e\n\nNow that your runtime and/or development environment is set up, to install the package simply run:\n\n```shell\nyarn \u0026\u0026 yarn build\n```\n\nAnd then start the CLI (always from the root of this repository):\n\n```shell\nyarn ardrive\n```\n\nFor convenience in the **non-developer case**, you can install the CLI globally on your system by performing the following step:\n\n```shell\nyarn pack\n\n# then using the path generated by yarn from the step above:\nnpm install i -g /path/to/package.tgz\n\n# then invoke the CLI from anywhere on your system:\nardrive\n```\n\n### Recommended Visual Studio Code extensions (Developers Only)\u003ca id=\"vs-extensions\"\u003e\u003c/a\u003e\n\nTo ensure your environment is compatible, we also recommend the following VSCode extensions:\n\n-   [ES-Lint][eslint-vscode]\n-   [Editor-Config][editor-config-vscode]\n-   [Prettier][prettier-vscode]\n-   [ZipFS][zipfs-vscode]\n\n## Limitations\n\n**Number of files in a bulk upload:** Theoretically unlimited\u003cbr\u003e\n**Max individual file size**: 2GB (Node.js limitation)\u003cbr\u003e\n**Max file name length**: 255 bytes\u003cbr\u003e\n**Max ANS-104 bundled transaction size:** 500 MiB per bundle. App will handle creating multiple bundles.\u003cbr\u003e\n**Max ANS-104 data item counts per bundled transaction:** 250 Files per bundle (500 Data Items).\n\n# Using the CLI\n\n## CLI Help\n\nLearn to use any command:\n\n```shell\nardrive --help\n```\n\n## CLI Version\n\nYou can print out the version by running any of:\n\n```shell\nardrive --version\nardrive -V\n```\n\n## Wallet Operations\n\nBrowsing of ArDrive public data is possible without the need for an [Arweave wallet][kb-wallets]. However, for all write operations, or read operations without encryption/decryption keys, you'll need a wallet.\n\nAs you utilize the CLI, you can use either your wallet file or your seed phrase interchangeably. Consider the security implications of each approach for your particular use case carefully. If at any time you'd like to generate a new wallet altogether, start by generating a new seed phase. And if you'd like to use that seed phrase in the form of a wallet file, or if you'd like to recover an existing wallet via its seed phrase, use either or both of the following commands:\n\n```shell\n# Generate seed-phrase\nardrive generate-seedphrase\n\"this is an example twelve word seed phrase that you could use\"\n\n# Generate/recover wallet file (with example output file path)\nardrive generate-wallet -s \"this is an example twelve word seed phrase that you could use\" \u003e /path/to/wallet/file.json\n```\n\nPublic attributes of Arweave wallets can be retrieved via their 43-character Arweave wallet address. You can retrieve the wallet address associated with [your wallet file or 12-word seed phrase][kb-wallets] (e.g. wallets generated by [ArConnect][arconnect]) like so:\n\n```shell\n# Wallet file\nardrive get-address -w /path/to/wallet/file.json\n\n# Seed Phrase (with sample output)\nardrive get-address -s \"this is an example twelve word seed phrase that you could use\"\nHTTn8F92tR32N8wuo-NIDkjmqPknrbl10JWo5MZ9x2k\n```\n\nYou'll need AR in your wallet for any write operations you perform in ArDrive. You can always check your wallet balance (in both AR and Winston units) by performing:\n\n```shell\n# Getting the balance for your own wallet\nardrive get-balance -w /path/to/wallet/file.json\n\n# Getting the balance for ANY wallet (with sample output)\nardrive get-balance -a \"HTTn8F92tR32N8wuo-NIDkjmqPknrbl10JWo5MZ9x2k\"\n1500000000000 Winston\n1.5 AR\n```\n\nIf, at any time, you need to send AR out of your wallet to another wallet address, you may perform:\n\n```shell\n# Using our previously generated wallet as the destination...\nardrive send-ar -w /path/to/wallet/file.json --dest-address \"HTTn8F92tR32N8wuo-NIDkjmqPknrbl10JWo5MZ9x2k\" --ar-amount 2.12345\n```\n\n## Working With Entities\n\n[ArDrive]'s [ArFS] integration provides for hierarchical organization of your file and folder data on Arweave.\n\nThe fundamental entity types specified by ArFS are:\n\n\u003cul\u003e\n\u003cli\u003eDrives\u003c/li\u003e\n\u003cli\u003eFolders\u003c/li\u003e\n\u003cli\u003eFiles\u003c/li\u003e\n\u003c/ul\u003e\n\nEach instance of these entities have a Version 4 UUID entity ID that is commonly referred to by its entity type, i.e. drive ID, folder ID, and file ID.\n\nWhen you execute write functions with the CLI, the JSON output will contain information about the Arweave Transaction IDs that were registered when writing your entities to the blockweave, any miner rewards or [ArDrive Community](https://ardrive.io/community/) tips that were disbursed from your wallet, and any new entity IDs and, when applicable, encryption keys that were generated in the process of creating the entities. Typically, you'll want to keep track of those and get proficient with retrieving them in order to build your drive hierarchy to your liking. See [Understanding Drive and File Keys](#understanding-drive-and-file-keys) for more info.\n\n### Dry Run\n\nAn important feature of the ArDrive CLI is the `--dry-run` flag. On each command that would write an ArFS entity, there is the option to run it as a \"dry run\". This will run all of the steps and print the outputs of a regular ArFS write, but will skip sending the actual transaction:\n\n```shell\nardrive \u003cmy-command\u003e \u003cother-options\u003e --dry-run\n```\n\nThis can be very useful for gathering price estimations or to confirm that you've copy-pasted your entity IDs correctly before committing to an upload.\n\n### Uploading to Turbo (BETA) \u003ca id=\"upload-to-turbo\"\u003e\u003c/a\u003e\n\nUsers can optionally choose to send each ArFS entities created to [ArDrive Turbo][ardrive-turbo] using the `--turbo` flag. Instead of using AR from an Arweave wallet, you can use Turbo Credits or take advantage of free/discounted upload promotions.\n\n```shell\nardrive \u003cmy-command\u003e \u003cother-options\u003e --turbo\n```\n\nThis flag will skip any balance check on the CLI side. Turbo will check a user's balance and accept/reject a data item at the time of upload. The `--turbo` flag by default will send your files to `upload.ardrive.io` to be bundled. To change the Turbo destination, users can use the `--turbo-url` flag.\n\n## Working With Drives\n\n### Understanding Drive Hierarchies\n\nAt the root of every data tree is a \"Drive\" entity. When a drive is created, a Root Folder is also created for it. The entity IDs for both are generated and returned when you create a new drive:\n\n```shell\n# Use `tee` to keep a receipt of the full set of transactions info and `jq` to focus on the data of interest\nardrive create-drive --wallet-file /path/to/my/wallet.json --drive-name \"Teenage Love Poetry\" |\ntee created_drive.json |\njq '[.created[] | del(.metadataTxId, .entityName, .bundledIn)]'\n[\n    {\n        \"type\": \"drive\",\n        \"entityId\": \"6939b9e0-cc98-42cb-bae0-5888eca78885\"\n    }\n    {\n        \"type\": \"folder\",\n        \"entityId\": \"d1535126-fded-4990-809f-83a06f2a1118\"\n    }\n]\n```\n\nThe relationship between the drive and its root folder is clearly visible when retrieving the drive's info:\u003ca id='drive-info'\u003e\u003c/a\u003e\n\n```shell\nardrive drive-info -d \"6939b9e0-cc98-42cb-bae0-5888eca78885\"\n| jq '{driveId, rootFolderId}'\n{\n    \"driveId\": \"6939b9e0-cc98-42cb-bae0-5888eca78885\",\n    \"rootFolderId\": \"d1535126-fded-4990-809f-83a06f2a1118\"\n}\n\n```\n\nAll file and folder entities in the drive will be anchored to it by a \"Drive-ID\" GQL Tag. And they'll each be anchored to a parent folder ID, tracked via the \"Parent-Folder-ID\" GQL tag, forming a tree structure whose base terminates at the Root Folder.\n\n### Understanding Drive and File Keys\n\nPrivate Drives achieve privacy via end-to-end encryption facilitated by hash-derived \"Keys\". Drive Keys encrypt/decrypt Drive and Folder data, and File Keys encrypt/decrypt File Data.\n\nThe relationships among your data and their keys is as follows:\n\n\u003cul\u003e\n\u003cli\u003eDrive Key = functionOf(Wallet Signature, Randomly Generated Drive ID, User-specified Drive Password)\u003c/li\u003e\n\u003cli\u003eFile Key = functionOf(Randomly Generated File ID, Drive Key)\u003c/li\u003e\n\u003c/ul\u003e\n\nWhen you create private entities, the returned JSON data from the ArDrive CLI will contain the keys needed to decrypt the encrypted representation of your entity that is now securely and permanently stored on the blockweave.\n\nTo derive the drive key again for a drive, perform the following:\u003ca id=\"derive-drive-key\"\u003e\u003c/a\u003e\n\n```shell\n# Will throw an error if the wallet or password specified can't be used to decrypt the on-chain drive\nardrive get-drive-key -w /path/to/my/wallet.json -d \"6939b9e0-cc98-42cb-bae0-5888eca78885\" -P\n```\n\nTo derive the file key again for a file, perform the following:\u003ca id=\"derive-file-key\"\u003e\u003c/a\u003e\n\n```shell\n# Will throw an error if the drive key or drive-key-derivation data specified can't be used to decrypt the on-chain file\nardrive get-file-key --file-id \"bd2ce978-6ede-4b0d-8f79-2d7bc235a0e0\" --drive-id \"6939b9e0-cc98-42cb-bae0-5888eca78885\" --drive-key \"yHdCjpCK3EcuhQcKNx2d/NN5ReEjoKfZVqKunlCnPEo\"\n```\n\n### Managing Drive Passwords\n\nThe ArDrive CLI's private drive and folder functions all require either a drive password OR a drive key. Private file functions require either the drive password or the file key. **Keys and passwords are sensitive data, so manage the entry, display, storage, and transmission of them very carefully.**\n\nDrive passwords are the most portable, and fundamental, encryption facet, so a few options are available during private drive operations for supplying them:\n\n\u003cul\u003e\n\u003cli\u003eEnvironment Variable\u003c/li\u003e\n\u003cli\u003eSTDIN\u003c/li\u003e\n\u003cli\u003eSecure Prompt\u003c/li\u003e\n\u003c/ul\u003e\n\n#### Supplying Your Password: Environment Variable\u003ca id=\"pw-environment-variable\"\u003e\u003c/a\u003e\n\n```shell\n# Securely type your password into a read prompt, store it to TMP_ARDRIVE_PW, and export it for the shell session\nread -rs TMP_ARDRIVE_PW\nexport ARDRIVE_DRIVE_PW=$(TMP_ARDRIVE_PW)\nardrive \u003csome private command\u003e -w /path/to/wallet.json -P\n```\n\n#### Supplying Your Password: STDIN\u003ca id=\"pw-stdin\"\u003e\u003c/a\u003e\n\n```shell\n# Pipe your drive password to the ArDrive CLI\ncat /path/to/my/drive/password.txt | ardrive \u003csome private command\u003e -w /path/to/wallet.json -P\n\n# Redirect your drive password to the ArDrive CLI\nardrive \u003csome private command\u003e -w /path/to/wallet.json -P \u003c /path/to/my/drive/password.txt\n```\n\n#### Supplying Your Password: Prompt\u003ca id=\"pw-prompt\"\u003e\u003c/a\u003e\n\n```shell\n# When all other options fail, the CLI will prompt for your password (NOT COMPATIBLE WITH PIPES AND REDIRECTS!)\nardrive \u003csome private command\u003e -w /path/to/wallet.json -P\n? Enter drive password: › ********\n```\n\n### Creating Drives\n\n```shell\n# Public drive\nardrive create-drive --wallet-file /path/to/my/wallet.json --drive-name \"My Public Archive\"\n\n# Private drive\nardrive create-drive --wallet-file /path/to/my/wallet.json --drive-name \"Teenage Love Poetry\" -P\n```\n\n### Listing Drives for an Address\n\nYou can list all the drives associated with any Arweave wallet address, though the details of private drives will be obfuscated from you unless you provide the necessary decryption data.\n\n```shell\n# List all your own drives\nardrive list-all-drives -w /path/to/my/wallet.json -P\n\n# List any address's drives\nardrive list-all-drives --address \"HTTn8F92tR32N8wuo-NIDkjmqPknrbl10JWo5MZ9x2k\"\n```\n\n### Listing Every Entity in a Drive\u003ca id=\"list-drive\"\u003e\u003c/a\u003e\n\nUseful notes on listing the contents of drives:\n\n\u003cul\u003e\n\u003cli\u003eListing a drive is effectively the same as listing its root folder.\u003c/li\u003e\n\u003cli\u003eYou can control the tree depth of the data returned.\u003c/li\u003e\n\u003cli\u003epath, txPath, and entityIdPath properties on entities can provide useful handholds for other forms of data navigation\u003c/li\u003e\n\u003c/li\u003e\n\n```shell\n# List everything in a private drive\nardrive list-drive -d \"c7f87712-b54e-4491-bc96-1c5fa7b1da50\" -w /path/to/my/wallet.json -P\n\n# List a private drive including the `fileKey` and/or `driveKey` of all listed entitites\nardrive list-drive -d \"c7f87712-b54e-4491-bc96-1c5fa7b1da50\" -w /path/to/my/wallet.json -P --with-keys\n\n# List the contents of a public drive up to and including those in the grandchild folders of the root folder\nardrive list-drive -d \"c7f87712-b54e-4491-bc96-1c5fa7b1da50\" --max-depth 2\n```\n\n### List Drive Pipeline Examples\n\nYou can utilize `jq` and the list commands to reshape the commands' output data into useful forms and stats for many use cases. Here are a few examples:\n\n\u003ca id=\"get-share-links\"\u003e\u003c/a\u003e\n\n```shell\n# Get share links for a PUBLIC drive\nardrive list-drive -d a44482fd-592e-45fa-a08a-e526c31b87f1 | jq '.[] | select(.entityType == \"file\") | \"https://app.ardrive.io/#/file/\" + .entityId + \"/view\"'\n```\n\nExample output:\n\n```shell\n\"https://app.ardrive.io/#/file/1337babe-f000-dead-beef-ffffffffffff/view\"\n\"https://app.ardrive.io/#/file/cdbc9ddd-1cab-41d9-acbd-fd4328929de3/view\"\n\"https://app.ardrive.io/#/file/f19bc712-b57a-4e0d-8e5c-b7f1786b34a1/view\"\n\"https://app.ardrive.io/#/file/4f8e081b-42f2-442d-be41-57f6f906e1c8/view\"\n\"https://app.ardrive.io/#/file/0e02d254-c853-4ff0-9b6e-c4d23d2a95f5/view\"\n\"https://app.ardrive.io/#/file/c098b869-29d1-4a86-960f-a9e10433f0b0/view\"\n\"https://app.ardrive.io/#/file/4afc8cdf-4d27-408a-bfb9-0a2ec21eebf8/view\"\n\"https://app.ardrive.io/#/file/85fe488d-fcf7-48ca-9df8-2b39958bbf15/view\"\n...\n```\n\n\u003ca id=\"get-total-size\"\u003e\u003c/a\u003e\n\n```shell\n# Get total size of all files within drive\nardrive list-drive -d 13c3c232-6687-4d11-8ac1-35284102c7db | jq ' map(select(.entityType == \"file\") | .size) | add'\n```\n\n\u003ca id=\"get-file-count\"\u003e\u003c/a\u003e\n\n```shell\n# Get total number of files within drive\nardrive list-drive -d 01ea6ba3-9e58-42e7-899d-622fd110211c | jq '[ .[] | select(.entityType == \"file\") ] | length'\n```\n\n## Working With Folders\n\nAs discussed previously, all folders in a drive are linked by way of parent folder references back to the root folder of a drive. Folders can be moved into any folder in the hierarchy that's not in their own subtree.\n\n### Creating Folders\n\nCreating folders manually is straightforward:\n\n```shell\nardrive create-folder --parent-folder-id \"63153bb3-2ca9-4d42-9106-0ce82e793321\" --folder-name \"My Awesome Folder\" -w /path/to/wallet.json\n```\n\nExample output:\n\n```shell\n{\n    \"created\": [\n        {\n            \"type\": \"folder\",\n            \"metadataTxId\": \"AYFMBVmwqhbg9y5Fbj3Iasy5oxUqhauOW7PcS1sl4Dk\",\n            \"entityId\": \"d1b7c514-fb12-4603-aad8-002cf63015d3\",\n            \"key\": \"yHdCjpCKD2cuhQcKNx2d/XF5ReEjoKfZVqKunlCnPEk\",\n            \"entityName\": \"My Awesome Folder\"\n        }\n    ],\n    \"tips\": [],\n    \"fees\": {\n        \"AYFMBVmwqhbg9y5Fbj3Iasy5oxUqhauOW7PcS1sl4Dk\": 1378052\n    }\n}\n```\n\nNote: Folders can also be created by supplying a folder as the --local-path of an upload-file command. In this case, the folder hierarchy on the local disk will be reconstructed on chain during the course of the recursive bulk upload.\n\n### Moving Folders\n\nMoving a folder is as simple as supplying a new parent folder ID. Note that naming collisions among entities within a folder are not allowed.\n\n```shell\nardrive move-folder --folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" --parent-folder-id \"29850ab7-56d4-4e1f-a5be-cb86d5513921\" -w /path/to/wallet.json\n```\n\n### Renaming Folders\u003ca id=\"rename-folder\"\u003e\u003c/a\u003e\n\nIn order to rename a folder you must provide a name different from its current one, and it must not create naming conflicts with its sibling entities.\n\n```shell\nardrive rename-folder --folder-id \"568d5eba-dbf3-4a49-8129-1c58f7fd35bc\" --folder-name \"Folder with cool stuff\" -w \"./wallet.json\"\n```\n\n### Viewing Folder Metadata\n\nTo view the metadata of a folder, users can use the `folder-info` command:\n\n```shell\nardrive folder-info --folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\"\n```\n\n### Listing Contents of a Folder\n\nSimilar to drives, the `list-folder` command can be used to fetch the metadata of each entity within a folder. But by default, the command will fetch only the immediate children of that folder (`--max-depth 0`):\n\n```shell\n# List immediate children of folder \"My Public Folder\"\nardrive list-folder --parent-folder-id \"29850ab7-56d4-4e1f-a5be-cb86d5513940\"\n```\n\nExample output:\n\n```shell\n[\n    {\n        \"appName\": \"ArDrive-CLI\",\n        \"appVersion\": \"2.0\",\n        \"arFS\": \"0.11\",\n        \"contentType\": \"application/json\",\n        \"driveId\": \"01ea6ba3-9e58-42e7-899d-622fd110211a\",\n        \"entityType\": \"folder\",\n        \"name\": \"mytestfolder\",\n        \"txId\": \"HYiKyfLwY7PT9NleTQoTiM_-qPVUwf4ClDhx1sjUAEU\",\n        \"unixTime\": 1635102772,\n        \"parentFolderId\": \"29850ab7-56d4-4e1f-a5be-cb86d5513940\",\n        \"entityId\": \"03df2929-1440-4ab4-bbf0-9dc776e1ed96\",\n        \"path\": \"/My Public Folder/mytestfolder\",\n        \"txIdPath\": \"/09_x0X2eZ3flXXLS72WdTDq6uaa5g2LjsT-QH1m0zhU/HYiKyfLwY7PT9NleTQoTiM_-qPVUwf4ClDhx1sjUAEU\",\n        \"entityIdPath\": \"/29850ab7-56d4-4e1f-a5be-cb86d5513940/03df2929-1440-4ab4-bbf0-9dc776e1ed96\"\n    },\n    {\n        \"appName\": \"ArDrive-CLI\",\n        \"appVersion\": \"2.0\",\n        \"arFS\": \"0.11\",\n        \"contentType\": \"application/json\",\n        \"driveId\": \"01ea6ba3-9e58-42e7-899d-622fd110211a\",\n        \"entityType\": \"folder\",\n        \"name\": \"Super sonic public folder\",\n        \"txId\": \"VUk1B_vo1va2-EHLtqjsotzy0Rdn6lU4hQo3RD2xoTI\",\n        \"unixTime\": 1631283259,\n        \"parentFolderId\": \"29850ab7-56d4-4e1f-a5be-cb86d5513940\",\n        \"entityId\": \"452c6aec-43dc-4015-9abd-20083068d432\",\n        \"path\": \"/My Public Folder/Super sonic sub folder\",\n        \"txIdPath\": \"/09_x0X2eZ3flXXLS72WdTDq6uaa5g2LjsT-QH1m0zhU/VUk1B_vo1va2-EHLtqjsotzy0Rdn6lU4hQo3RD2xoTI\",\n        \"entityIdPath\": \"/29850ab7-56d4-4e1f-a5be-cb86d5513940/452c6aec-43dc-4015-9abd-20083068d432\"\n    },\n    {\n        \"appName\": \"ArDrive-CLI\",\n        \"appVersion\": \"2.0\",\n        \"arFS\": \"0.11\",\n        \"contentType\": \"application/json\",\n        \"driveId\": \"01ea6ba3-9e58-42e7-899d-622fd110211a\",\n        \"entityType\": \"file\",\n        \"name\": \"test-number-twelve.txt\",\n        \"txId\": \"429zBqnd7ZBNzgukaix26RYz3g5SeXCCo_oIY6CPZLg\",\n        \"unixTime\": 1631722234,\n        \"size\": 47,\n        \"lastModifiedDate\": 1631722217028,\n        \"dataTxId\": \"vA-BxAS7I6n90cH4Fzsk4cWS3EOPb1KOhj8yeI88dj0\",\n        \"dataContentType\": \"text/plain\",\n        \"parentFolderId\": \"29850ab7-56d4-4e1f-a5be-cb86d5513940\",\n        \"entityId\": \"e5948327-d6de-4acf-a6fe-e091ecf78d71\",\n        \"path\": \"/My Public Folder/test-number-twelve.txt\",\n        \"txIdPath\": \"/09_x0X2eZ3flXXLS72WdTDq6uaa5g2LjsT-QH1m0zhU/429zBqnd7ZBNzgukaix26RYz3g5SeXCCo_oIY6CPZLg\",\n        \"entityIdPath\": \"/29850ab7-56d4-4e1f-a5be-cb86d5513940/e5948327-d6de-4acf-a6fe-e091ecf78d71\"\n    },\n    {\n        \"appName\": \"ArDrive-CLI\",\n        \"appVersion\": \"2.0\",\n        \"arFS\": \"0.11\",\n        \"contentType\": \"application/json\",\n        \"driveId\": \"01ea6ba3-9e58-42e7-899d-622fd110211a\",\n        \"entityType\": \"file\",\n        \"name\": \"wonderful-test-file.txt\",\n        \"txId\": \"6CokwlzB81Fx7dq-lB654VM0XQykdU6eYohDmEJ2gk4\",\n        \"unixTime\": 1631671275,\n        \"size\": 23,\n        \"lastModifiedDate\": 1631283389232,\n        \"dataTxId\": \"UP8THwA_1gvyRqNRqYmTpWvU4-UzNWBN7SiX_AIihg4\",\n        \"dataContentType\": \"text/plain\",\n        \"parentFolderId\": \"29850ab7-56d4-4e1f-a5be-cb86d5513940\",\n        \"entityId\": \"3274dae9-3487-41eb-94d5-8d5d3d8bc343\",\n        \"path\": \"/My Public Folder/wonderful-test-file.txt\",\n        \"txIdPath\": \"/09_x0X2eZ3flXXLS72WdTDq6uaa5g2LjsT-QH1m0zhU/6CokwlzB81Fx7dq-lB654VM0XQykdU6eYohDmEJ2gk4\",\n        \"entityIdPath\": \"/29850ab7-56d4-4e1f-a5be-cb86d5513940/3274dae9-3487-41eb-94d5-8d5d3d8bc343\"\n    }\n]\n```\n\nTo list further than the immediate children, you can make use of the flags: `--all` and `--max-depth`.\n\n```shell\n# List all contents of a public folder\nardrive list-folder --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" --all\n\n# List the contents of a public folder with custom depth\nardrive list-folder --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" --max-depth 2\n```\n\nIn the case of private entitites, the `--with-keys` flag will make the command to include the keys in the output.\n\n```shell\n# List all contents of a private folder including the `fileKey` and/or `driveKey` of all listed entitites\nardrive list-folder --parent-folder-id \"1b027047-4cfc-4eee-88a8-9af694f660c0\" -w /my/wallet.json --with-keys\n```\n\n## Working With Files\n\nSimilar to folders, files are linked to a parent folder which ultimately chains the file back to the root folder of its parent drive. As such, a parent folder ID is required in order to upload files. Files can be freely moved to other folders within their original drive.\n\nThe important difference for file entities is that they also hold a reference to their data transaction ID, which is the `dataTxId` as returned by the `file-info` command. This is where your uploaded data lives on the permaweb.\n\n**NOTE: The CLI currently (v1.0.0) has progress logging on uploads DISABLED for producing clean JSON outputs that can be piped in the terminal. On larger uploads, remember to be patient. You can check your system's `node` process to confirm the process is still uploading.**\n\n### Uploading a Single File\n\nTo upload a file, you'll need a parent folder id, the file to upload's file path, and the path to your wallet:\n\n```shell\n# Supply the parent folder ID to upload-file\nardrive upload-file --local-path /path/to/file.txt  --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\nExample output:\n\n```shell\n{\n    \"created\": [\n        {\n            \"type\": \"file\",\n            \"entityName\": \"file.txt\"\n            \"entityId\": \"6613395a-cf19-4420-846a-f88b7b765c05\"\n            \"dataTxId\": \"l4iNWyBapfAIj7OU-nB8z9XrBhawyqzs5O9qhk-3EnI\",\n            \"metadataTxId\": \"YfdDXUyerPCpBbGTm_gv_x5hR3tu5fnz8bM-jPL__JE\",\n            \"bundledIn\": \"1zwdfZAIV8E26YjBs2ZQ4xjjP_1ewalvRgD_GyYw7f8\",\n            \"sourceUri\": \"file:///path/to/file.txt\"\n        },\n        {\n            \"type\": \"bundle\",\n            \"bundleTxId\": \"1zwdfZAIV8E26YjBs2ZQ4xjjP_1ewalvRgD_GyYw7f8\"\n        }\n    ],\n    \"tips\": [\n        {\n            \"txId\": \"1zwdfZAIV8E26YjBs2ZQ4xjjP_1ewalvRgD_GyYw7f8\",\n            \"recipient\": {\n                \"address\": \"3mxGJ4xLcQQNv6_TiKx0F0d5XVE0mNvONQI5GZXJXkt\"\n            },\n            \"winston\": \"10000000\"\n        }\n    ],\n    \"fees\": {\n        \"1zwdfZAIV8E26YjBs2ZQ4xjjP_1ewalvRgD_GyYw7f8\": 42819829\n    }\n}\n```\n\nNOTE: To upload to the root of a drive, specify its root folder ID as the parent folder ID for the upload destination. You can retrieve it like so:\n\n```shell\nardrive drive-info -d \"c7f87712-b54e-4491-bc96-1c5fa7b1da50\" | jq -r '.rootFolderId'\n```\n\n### IPFS CID Tagging\n\nCertain nodes on the Arweave network may be running the [IPFS+Arweave bridge](https://arweave.medium.com/arweave-ipfs-persistence-for-the-interplanetary-file-system-9f12981c36c3). Tagging your file upload transaction with its IPFS v1 CID value in the 'IPFS-Add' tag may allow you to take advantage of this system. It can also be helpful for finding data on Arweave via GQL based on its CID. To include the CID tag on your **PUBLIC** file uploads, you may use the '--add-ipfs-tag' flag:\n\n```shell\nardrive upload-file --add-ipfs-tag --local-path /path/to/file.txt  --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\n### Progress Logging of Transaction Uploads\n\nProgress logging of transaction uploads to stderr can be enabled by setting the `ARDRIVE_PROGRESS_LOG` environment variable to `1`:\n\n```shell\nUploading file transaction 1 of total 2 transactions...\nTransaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 0%\nTransaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 35%\nTransaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 66%\nTransaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 100%\nUploading file transaction 2 of total 2 transactions...\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 0%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 13%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 28%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 42%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 60%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 76%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 91%\nTransaction nA1stCdTkuf290k0qsqvmJ78isEC0bwgrAi3D8Cl1LU Upload Progress: 100%\n```\n\n### Download a Single file (BETA)\u003ca id=\"download-file\"\u003e\u003c/a\u003e\n\nBy using the `download-file` command you can download a file on chain to a folder in your local storage specified by --local-path (or to your current working directory if not specified):\n\n```shell\nardrive download-file -w /path/to/wallet.json --file-id \"ff450770-a9cb-46a5-9234-89cbd9796610\" --local-path /my_ardrive_downloads/\n```\n\nSpecify a filename in the --local-path if you'd like to use a different name than the one that's used in your drive:\n\n```shell\nardrive download-file -w /path/to/wallet.json --file-id \"ff450770-a9cb-46a5-9234-89cbd9796610\" --local-path /my_ardrive_downloads/my_pic.png\n```\n\n### Rename a Single File\u003ca id=\"rename-file\"\u003e\u003c/a\u003e\n\nTo rename an on-chain file you can make use of the `rename-file` command. The required parameters are the file ID and the new name, as well as the owner wallet or seed phrase.\n\n```shell\nardrive rename-file --file-id \"290a3f9a-37b2-4f0f-a899-6fac983833b3\" --file-name \"My custom file name.txt\" --wallet-file \"wallet.json\"\n```\n\n### Uploading a Folder with Files (Bulk Upload)\u003ca id=\"bulk-upload\"\u003e\u003c/a\u003e\n\nUsers can perform a bulk upload by using the upload-file command on a target folder. The command will reconstruct the folder hierarchy on local disk as ArFS folders on the permaweb and upload each file into their corresponding folders:\n\n```shell\nardrive upload-file --local-path /path/to/folder --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\n### Downloading a Folder with Files\u003ca id=\"download-folder\"\u003e\u003c/a\u003e\n\nYou can download a folder from ArDrive to your local machine with the `download-folder` command. In the following examples, assume that a folder with ID \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" exists in your drive and is named \"MyArDriveFolder\".\n\n```shell\n# Downloads \"MyArDriveFolder\" into the current working directory, i.e. ./MyArDriveFolder/\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\"\n```\n\nBy specifying the `--local-path` option, you can choose the local parent folder into which the on-chain folder will be downloaded. When the parameter is omitted, its value defaults to the current working directory (i.e. `./`).\n\n```shell\n# Downloads \"MyArDriveFolder\" into /my_ardrive_downloads/MyArDriveFolder\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --local-path /my_ardrive_downloads/\n```\n\nThe `--max-depth` parameter lets you to choose a custom folder depth to download. When omitted, the entire subtree of the folder will be downloaded. In the following example, only the immediate children of the folder will be downloaded:\n\n```shell\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --max-depth 0\n```\n\nThe behaviors of `--local-path` are similar to those of `cp` and `mv` in Unix systems, e.g.:\n\n```shell\n# folder downloaded to \"/existing_folder/MyArDriveFolder\"\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --local-path \"/existing_folder\"\n\n# folder downloaded to \"/existing_folder/MyArDriveFolder/MyArDriveFolder\" as \"/existing_folder/MyArDriveFolder\" already exists\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --local-path \"/existing_folder/MyArDriveFolder\"\n\n# folder downloaded to \"/existing_folder/non_existent_folder\"\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --local-path \"/existing_folder/non_existent_folder\"\n\n# ERROR!\nardrive download-folder -f \"47f5bde9-61ba-49c7-b409-1aa4a9e250f6\" --local-path \"/non_existent_folder_1/non_existent_folder_2\"\n```\n\n### Downloading a Drive\u003ca id=\"download-drive\"\u003e\n\nTo download the whole drive you can use the `download-drive` command.\n\n```shell\nardrive download-drive -d \"c0c8ba1c-efc5-420d-a07c-a755dc67f6b2\"\n```\n\nThis is equivalent to running the `download-folder` command against the root folder of the drive.\n\n### Uploading Multiple Files\u003ca id=\"multi-file-upload\"\u003e\u003c/a\u003e\n\nTo upload an arbitrary number of files or folders, pass a space-separated list of paths to `--local-paths`:\n\n```shell\n# Specifying a mixed set of file and folder paths\nardrive upload-file -w wallet.json -F \"6939b9e0-cc98-42cb-bae0-5888eca78885\" --local-paths ./image.png ~/backups/ ../another_file.txt\n\n# Example using glob expansion to upload all .json files in the current folder\nardrive upload-file -w wallet.json -F \"6939b9e0-cc98-42cb-bae0-5888eca78885\" --local-paths ./*.json\n```\n\n### Name Conflict Resolution on Upload\u003ca id=\"conflict-resolution\"\u003e\u003c/a\u003e\n\nBy default, the `upload-file` command will use the upsert behavior if existing entities are encountered in the destination folder tree that would cause naming conflicts.\n\nExpect the behaviors from the following table for each of these resolution settings:\n\n| Source Type | Conflict at Dest | `skip` | `replace` | `upsert` (default) |\n| ----------- | ---------------- | ------ | --------- | ------------------ |\n| File        | None             | Insert | Insert    | Insert             |\n| File        | Matching File    | Skip   | Update    | Skip               |\n| File        | Different File   | Skip   | Update    | Update             |\n| File        | Folder           | Skip   | Fail      | Fail               |\n| Folder      | None             | Insert | Insert    | Insert             |\n| Folder      | File             | Skip   | Fail      | Fail               |\n| Folder      | Folder           | Re-use | Re-use    | Re-use             |\n\nThe default upsert behavior will check the destination folder for a file with a conflicting name. If no conflicts are found, it will insert (upload) the file.\n\nIn the case that there is a FILE to FILE name conflict found, it will only update it if necessary. To determine if an update is necessary, upsert will compare the last modified dates of conflicting file and the file being uploaded. When they are matching, the upload will be skipped. Otherwise the file will be updated as a new revision.\n\nTo override the upsert behavior, use the `--replace` option to always make new revisions of a file or the `--skip` option to always skip the upload on name conflicts:\n\n```shell\nardrive upload-file --replace --local-path /path/to/file.txt  --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\n```shell\nardrive upload-file --skip --local-path /path/to/file.txt  --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\nAlternatively, the upload-file commands now also supports the `--ask` conflict resolution option. This setting will always provide an interactive prompt on name conflicts that allows users to decide how to resolve each conflict found:\n\n```shell\nardrive upload-file --ask --local-file-path /path/to/file.txt  --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n\nDestination folder has a file to file name conflict!\n\nFile name: 2.png\nFile ID: efbc0370-b69f-44d9-812c-0d272b019027\nThis file has a DIFFERENT last modified date\n\nPlease select how to proceed:\n › - Use arrow-keys. Return to submit.\n❯   Replace as new file revision\n    Upload with a different file name\n    Skip this file upload\n```\n\n### Understanding Bundled Transactions\u003ca id=\"bundles\"\u003e\u003c/a\u003e\n\nThe ArDrive CLI currently uses two different methods for uploading transactions to the Arweave network: standard transactions and Direct to Network (D2N) bundled transactions. By default, the CLI will send a D2N bundled transaction for any action that would result in multiple transactions. This bundling functionality is currently used on the `upload-file` and `create-drive` commands.\n\nD2N bundled transactions come with several benefits and implications:\n\n-   Bundling saves AR and enhances ArFS reliability by sending associated ArFS transactions up as one atomic bundle.\n-   Bundled transactions are treated as a single data transaction by the Arweave network, but can be presented as separate transactions by the Arweave Gateway once they have been \"unbundled\".\n-   Un-bundling can take anywhere from a few minutes up to an hour. During that time, the files in the bundle will neither appear in list- commands nor be downloadable. Similarly, they will not appear in the web app after syncs until un-bundling is complete. **This can negatively affect the accuracy of upsert operations**, so it's best to wait before retrying bulk uploads.\n-   Bundling reliability on the gateway side degrades once bundles reach either 500 data items (or ~250 files) or 500 MiB, so the CLI will create and upload multiple bundles as necessary, or will send files that are simply too large for reliable bundling as unbundled txs.\n\n### Uploading a Non-Bundled Transaction (NOT RECOMMENDED)\u003ca id=\"no-bundle\"\u003e\u003c/a\u003e\n\nWhile not recommended, the CLI does provide the option to forcibly send all transactions as standard transactions rather than attempting to bundle them together. To do this, simply add the `--no-bundle` flag to the `upload-file` or `create-drive` command:\n\n```shell\nardrive upload-file --no-bundle --local-path /path/to/file --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\n### Fetching the Metadata of a File Entity\n\nSimply perform the file-info command to retrieve the metadata of a file:\n\n```shell\nardrive file-info --file-id \"e5ebc14c-5b2d-4462-8f59-7f4a62e7770f\"\n```\n\nExample output:\n\n```shell\n{\n    \"appName\": \"ArDrive-Web\",\n    \"appVersion\": \"0.1.0\",\n    \"arFS\": \"0.11\",\n    \"contentType\": \"application/json\",\n    \"driveId\": \"51062487-2e8b-4af7-bd81-4345dc28ea5d\",\n    \"entityType\": \"file\",\n    \"name\": \"2_depth.png\",\n    \"txId\": \"CZKdjqwnmxbWchGA1hjSO5ZH--4OYodIGWzI-FmX28U\",\n    \"unixTime\": 1633625081,\n    \"size\": 41946,\n    \"lastModifiedDate\": 1605157729000,\n    \"parentFolderId\": \"a2c8a0cb-0ca7-4dbb-8bf8-93f75f308e63\",\n    \"entityId\": \"e5ebc14c-5b2d-4462-8f59-7f4a62e7770f\",\n    \"fileId\": \"e5ebc14c-5b2d-4462-8f59-7f4a62e7770f\",\n    \"dataTxId\": \"Jz0WsWyAGVc0aE3UzACo-YJqG8OPrN3UucmDdt8Fbjc\",\n    \"dataContentType\": \"image/png\"\n}\n```\n\n### Retrying a Failed File Data Transaction (Public Unbundled Files Only)\u003ca id=\"retry-tx\"\u003e\u003c/a\u003e\n\nArweave data upload transactions are split into two phases: transaction posting and chunks uploading. Once the transaction post phase has been completed, you've effectively \"paid\" the network for storage of the data chunks that you'll send in the next stage.\n\nIf your system encounters an error while posting the transaction, you can retry posting the transaction for as long as your tx_anchor is valid ([learn more about tx_anchors here][tx_anchors]). You may retry and/or resume posting chunks at any time after your transaction has posted. The ArDrive CLI allows you to take advantage of this Arweave protocol capability.\n\nUsing the CLI, when the transaction post has succeeded but the chunk upload step fails, the data transaction's ID could be lost. There are a few options to recover this ID. If the failed transaction is the most recent one sent from a wallet, the transaction ID can be recovered with the `ardrive last-tx -w /path/to/wallet` command AFTER the transaction's headers have been mined (It can take 5-10 minutes for the tx-id to become available with the last-tx approach). Other options for finding the partially uploaded transaction's ID include:\n\n-   Using an Arweave gateway GQL http endpoint to search for transactions that belong to the wallet. See this [Arweave GQL Guide][gql-guide] for more info.\n-   Browse the recent transactions associated with the wallet via a block explorer tool like [ViewBlock][viewblock].\n\nIn order to re-seed the chunks for an unbundled ArFS data transaction, a user must have the data transaction ID, the original file data, and either a destination folder ID or a valid file ID for the file. Supply that information to the `retry-tx` command like so:\n\n```shell\nardrive retry-tx --tx-id { Data Transaction ID } --parent-folder-id { Destination Folder ID }  --local-path /path/to/file  --wallet-file /path/to/wallet\n```\n\n**Note: Retry feature is currently only available for PUBLIC unbundled file transactions. It is also perfectly safe to mistakenly re-seed the chunks of a healthy transaction, the transaction will remain stable and the wallet balance will not be affected.**\n\n### Moving Files\u003ca id=\"moving-files\"\u003e\u003c/a\u003e\n\nFiles can be moved from one folder to another within the same drive. Moving a file is simply the process of uploading a new file metadata revision with an updated File ID \u003c\u003e Parent Folder ID relationship. The following command will move a file from its current location in a public drive to a new parent folder in that drive:\n\n```shell\nardrive move-file --file-id \"e5ebc14c-5b2d-4462-8f59-7f4a62e7770f\" --parent-folder-id \"a2c8a0cb-0ca7-4dbb-8bf8-93f75f308e63\"\n```\n\n### Uploading Manifests\n\n[Arweave Path Manifests][arweave-manifests] are are special `.json` files that instruct Arweave Gateways to map file data associated with specific, unique transaction IDs to customized, hosted paths relative to that of the manifest file itself. So if, for example, your manifest file had an arweave.net URL like:\n\n```shell\nhttps://arweave.net/{manifest tx id}\n```\n\nThen, all the mapped transactions and paths in the manifest file would be addressable at URLs like:\n\n```shell\nhttps://arweave.net/{manifest tx id}/foo.txt\nhttps://arweave.net/{manifest tx id}/bar/baz.png\n```\n\nArDrive supports the creation of these Arweave manifests using any of your PUBLIC folders. The generated manifest paths will be links to each of the file entities within the specified folder. The manifest file entity will be created at the root of the folder.\n\nTo create a manifest of an entire public drive, specify the root folder of that drive:\n\n```shell\nardrive create-manifest -f \"bc9af866-6421-40f1-ac89-202bddb5c487\" -w \"/path/to/wallet\"\n```\n\nYou can also create a manifest of a folder's file entities at a custom depth by using the `--max-depth` option:\n\n```shell\n# Create manifest of a folder's local file contents, excluding all sub-folders\nardrive create-manifest --max-depth 0  -f \"867228d8-4413-4c0e-a499-e1decbf2ea38\" -w \"/path/to/wallet\"\n```\n\nCreating a `.json` file of your manifest links output can be accomplished here with some `jq` parsing and piping to a file:\n\n```shell\nardrive create-manifest -w /path/to/wallet -f \"6c312b3e-4778-4a18-8243-f2b346f5e7cb\"  | jq '{links}' \u003e links.json\n```\n\nIf you'd like to preview the contents of your manifest before uploading, you can perform a dry run and do some lightweight post processing to isolate the data:\n\n```shell\nardrive create-manifest -w /path/to/wallet -f \"6c312b3e-4778-4a18-8243-f2b346f5e7cb\"  --dry-run | jq '{manifest}.manifest'\n```\n\n\u003ca id=\"manifest-json\"\u003e\u003c/a\u003e\n\n```json\n{\n    \"manifest\": \"arweave/paths\",\n    \"version\": \"0.1.0\",\n    \"index\": {\n        \"path\": \"index.html\"\n    },\n    \"paths\": {\n        \"hello_world.txt\": {\n            \"id\": \"Y7GFF8r9y0MEU_oi1aZeD87vrmai97JdRQ2L0cbGJ68\"\n        },\n        \"index.html\": {\n            \"id\": \"pELonjVebHyBsdxVymvxbGTmHD96v9PuuUXj8GUHGoY\"\n        }\n    }\n}\n```\n\nThe manifest data transaction is tagged with a unique content-type, `application/x.arweave-manifest+json`, which tells the gateway to treat this file as a manifest. The manifest file itself is a `.json` file that holds the paths (the data transaction ids) to each file within the specified folder.\n\nWhen your folder is later changed by adding files or updating them with new revisions, the original manifest will NOT be updated on its own. A manifest is a permanent record of your files in their current state.\n\nHowever, creating a subsequent manifest with the same manifest name will create a new revision of that manifest in its new current state. Manifests follow the same name conflict resolution as outlined for files above (upsert by default).\n\n#### Hosting a Webpage with Manifest\n\nWhen creating a manifest, it is possible to host a webpage or web app. You can do this by creating a manifest on a folder that has an `index.html` file in its root.\n\nUsing generated build folders from popular frameworks works as well. One requirement here to note is that the `href=` paths from your generated `index.html` file must not have leading a `/`. This means that the manifest will not resolve a path of `/dist/index.js` but it will resolve `dist/index.js` or `./dist/index.js`.\n\nAs an example, here is a flow of creating a React app and hosting it with an ArDrive Manifest. First, generate a React app:\n\n```shell\nyarn create react-app my-app\n```\n\nNext, add this field to the generated `package.json` so that the paths will resolve correctly:\n\n```json\n\"homepage\": \".\",\n```\n\nThen, create an optimized production build from within the app's directory:\n\n```shell\nyarn build\n```\n\nNow, we can create and upload that produced build folder on ArDrive to any of your existing ArFS folder entities:\n\n```shell\nardrive upload-file -l \"/build\" -w \"/path/to/wallet\" --parent-folder-id \"bc9af866-6421-40f1-ac89-202bddb5c487\"\n```\n\nAnd finally, create the manifest using the generated Folder ID from the build folder creation:\n\n```shell\n# Create manifest using the Folder ID of the `/build` folder\nardrive create-manifest -f \"41759f05-614d-45ad-846b-63f3767504a4\" -w \"/path/to/wallet\"\n```\n\nIn the return output, the top link will be a link to the deployed web app:\n\n```shell\n    \"links\": [\n        \"https://arweave.net/0MK68J8TqGhaaOpPe713Zn0jdpczMt2NGS2CtRYiuAg\",\n        \"https://arweave.net/0MK68J8TqGhaaOpPe713Zn0jdpczMt2NGS2CtRYiuAg/asset-manifest.json\",\n        \"https://arweave.net/0MK68J8TqGhaaOpPe713Zn0jdpczMt2NGS2CtRYiuAg/favicon.ico\",\n        \"https://arweave.net/0MK68J8TqGhaaOpPe713Zn0jdpczMt2NGS2CtRYiuAg/index.html\",\n        # ...\n```\n\nThis is effectively hosting a web app with ArDrive. Check out the ArDrive Price Calculator React App hosted as an [ArDrive Manifest][example-manifest-webpage].\n\n### Uploading With a Custom Content Type\u003ca id=\"custom-content-type\"\u003e\u003c/a\u003e\n\nEach file uploaded to the Arweave network receives a `\"Content-Type\"` GraphQL tag that contains the MIME type for the file. The gateway will use this content type to determine how to serve that file's data transaction at the `arweave.net/{data tx id}` endpoint.\n\nBy default, the CLI will attempt to derive this content type from the file extension of the provided file. In most cases, the content type that is derived will be correct and the gateway will properly serve the file.\n\nThe CLI also provides the option for users to upload files with a custom content type using the `--content-type` flag:\n\n```shell\nardrive upload-file --content-type \"application/json\"  --local-path /path/to/file --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\nIt is currently possible to set this value to any given string, but the gateway will still only serve valid content types. Check out this list of commonly used MIME types to ensure you're providing a valid content type: [Common MIME types][mozilla-mime-types].\n\nNote: In the case of multi-file uploads or recursive folder uploads, setting this `--content-type` flag will set the provided custom content type on EVERY file entity within a given upload.\n\n### Uploading From a Remote URL\u003ca id=\"remote-path\"\u003e\u003c/a\u003e\n\nYou can upload a file from an existing url using the `--remote-path` flag. This must be used in conjunction with `--dest-file-name`.\n\nYou can use a custom content type using the `--content-type` flag, but if this isn't used the app will use the content type from the response header of the request for the remote data.\n\n```shell\nardrive upload-file --remote-path \"https://url/to/file\" --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -d \"example.jpg\" -w /path/to/wallet.json\n```\n\n### Uploading a Custom Manifest\u003ca id=\"custom-manifest\"\u003e\u003c/a\u003e\n\nUsing the custom content type feature, it is possible for users to upload their own custom manifests. The Arweave gateways use this special content type in order to identify an uploaded file as a manifest:\n\n```shell\napplication/x.arweave-manifest+json\n```\n\nIn addition to this content type, the manifest must also adhere to the [correct JSON structure](#manifest-json) of an Arweave manifest. A user can create their own manifest from scratch, or start by piping a generated manifest to a JSON file and editing it to their specifications:\n\n```shell\nardrive create-manifest -w /path/to/wallet -f \"6c312b3e-4778-4a18-8243-f2b346f5e7cb\"  --dry-run | jq '{manifest}.manifest' \u003e my-custom-manifest.json\n```\n\nAfter editing the generated manifest, simply perform an `upload-file` command with the custom Arweave manifest content type to any PUBLIC folder:\n\n```shell\nardrive upload-file --content-type \"application/x.arweave-manifest+json\" --local-path my-custom-manifest.json --parent-folder-id \"9af694f6-4cfc-4eee-88a8-1b02704760c0\" -w /path/to/wallet.json\n```\n\nThe returned `dataTxId` field on the created `file` entity will be the endpoint that the manifest can be found on Arweave, just as explained in the [manifest sections](#uploading-manifests) above:\n\n```shell\nhttps://arweave.net/{dataTxId}\nhttps://arweave.net/{dataTxId}/custom-file-1\nhttps://arweave.net/{dataTxId}/custom-file-2\n```\n\n### Uploading Files with Custom MetaData\n\nArDrive CLI has the capability of attaching custom metadata to ArFS File and Folder MetaData Transactions during the `upload-file` command. This metadata can be applied to either the GQL tags on the MetaData Transaction and/or into the MetaData Transaction's Data JSON.\n\nAll custom metadata applied must ultimately adhere to the following JSON shapes:\n\n```ts\n// GQL Tags\ntype CustomMetaDataGqlTags = Record\u003cstring, string | string[]\u003e;\n\n// Data JSON Fields\ntype CustomMetaDataJsonFields = Record\u003cstring, JsonSerializable\u003e;\n\nexport type JsonSerializable =\n    | string\n    | number\n    | boolean\n    | null\n    | { [member: string]: JsonSerializable }\n    | JsonSerializable[];\n```\n\ne.g:\n\n```shell\n{ IPFS-Add: 'MY_HASH' }\n# or\n{ 'Custom Name': ['Val 1', 'Val 2'] }\n```\n\nWhen the custom metadata is attached to the MetaData Transaction's GQL tags, they will become visible on any Arweave GQL gateway and also third party tools that read GQL data.\n\nWhen these tags are added to the MetaData Transaction's Data JSON they can be read by downloading the JSON data directly from `https://arweave.net/METADATA_TX_ID`.\n\nTo add this custom metadata to your file metadata transactions, CLI users can pass custom metadata these parameters:\n\n-   `--metadata-file path/to/json/schema`\n-   `--metadata-json '{\"key\": \"val\", \"key-2\": true, \"key-3\": 420, \"key-4\": [\"more\", 1337]}'`\n-   `--metadata-gql-tags \"Tag-Name\" \"Tag Val\"`\n\nThe `--metadata-file` will accept a file path to JSON file containing custom metadata:\n\n```shell\nardrive upload-file --metadata-file path/to/metadata/json # ...\n```\n\nThis JSON schema object must contain instructions on where to put this metadata with the `metaDataJson` and `metaDataGqlTags` keys. e.g:\n\n```json\n{\n    \"metaDataJson\": {\n        \"Tag-Name\": [\"Value-1\", \"Value-2\"]\n    },\n    \"metaDataGqlTags\": {\n        \"GQL Tag Name\": \"Tag Value\"\n    }\n}\n```\n\nThe `--metadata-gql-tags` parameter accepts an array of string values to be applied to the MetaData Tx GQL Tags. This method of CLI input does not support multiple tag values for a given tag name and the input must be an EVEN number of string values. (Known bug: String values starting with the `\"-\"` character are currently not supported. Use --metadata-file parameter instead.) e.g:\n\n```shell\nupload-file --metadata-gql-tags \"Custom Tag Name\" \"Custom Value\" # ...\n```\n\nAnd the `--metadata-json` parameter will accept a stringified JSON input. It will apply all declared JSON fields directly to the MetaData Tx's Data JSON. e.g:\n\n```shell\n upload-file --metadata-json ' { \"json field\": \"value\", \"another fields\": false } ' # ...\n```\n\nCustom metadata applied to files and/or folders during the `upload-file` command will be read back through all existing read commands. e.g:\n\n```shell\nardrive file-info -f 067c4008-9cbe-422e-b697-05442f73da2b\n{\n    \"appName\": \"ArDrive-CLI\",\n    \"appVersion\": \"1.17.0\",\n    \"arFS\": \"0.11\",\n    \"contentType\": \"application/json\",\n    \"driveId\": \"967215ca-a489-494b-97ec-0dd428d7be34\",\n    \"entityType\": \"file\",\n    \"name\": \"unique-name-9718\",\n    \"txId\": \"sxg8bNu6_bbaHkJTxAINVVoz_F-LiFe6s7OnxzoJJk4\",\n    \"unixTime\": 1657655070,\n    \"size\": 262148,\n    \"lastModifiedDate\": 1655409872705,\n    \"dataTxId\": \"ublZcIff77ejl3m0uEA8lXEfnTWmSBOFoz-HibqKeyk\",\n    \"dataContentType\": \"text/plain\",\n    \"parentFolderId\": \"97bc4fb5-aca4-4ffe-938f-1285153d98ca\",\n    \"entityId\": \"067c4008-9cbe-422e-b697-05442f73da2b\",\n    \"fileId\": \"067c4008-9cbe-422e-b697-05442f73da2b\",\n    \"IPFS-Add\": \"MY_HASH\",\n    \"Tag-1\": \"Val\",\n    \"Tag-2\": \"Val\",\n    \"Tag-3\": \"Val\",\n    \"Boost\": \"1.05\"\n}\n```\n\n#### Applying Unique Custom MetaData During Bulk Workflows\n\nWith some custom scripting and the `--metadata-file` parameter, the ArDrive CLI can be used to apply custom metadata to each file individually in a bulk workflow. For example, if you choose a numbered file naming pattern you can make use of a `for` loop:\n\n```shell\nfor i in {1..5}\ndo\nardrive upload-file -F f0c58c11-430c-4383-8e54-4d864cc7e927 --local-path \"../uploads/test-file-$i.txt\" -w \"/path/to/wallet.json\" --metadata-file \"../custom/metadata-$i.json\" --dry-run \u003e \"file-result-$i.json\"\ndone\n```\n\n## Other Utility Operations\n\n### Monitoring Transactions\n\nBlock time on Arweave is typically between 2-3 minutes in duration, so transactions can be mined within that time frame when [network congestion](#dealing-with-network-congestion) is low. Transactions, in the general case, proceed through the following set of states:\n\n-   Pending: the transaction is waiting the \"mempool\" to be mined\n-   Confirming: the transaction was mined on an Arweave Node, but has not yet been confirmed by at least 15 total nodes on the network\n-   Confirmed: the transaction was mined on an Arweave Node and confirmed by at least 15 total nodes on the network\n-   Not Found: the transaction is not available for any of the following reasons:\n    -   Insufficient reward to join the mempool\n    -   Insufficient reward to be mined within 50 blocks during a period of network congestion\n    -   Transaction is transitioning between states\n    -   Transaction ID is invalid\n\nMonitor any Arweave transaction's status via its transaction ID by performing:\n\n```shell\n# Peek at the status:\nardrive tx-status -t \"ekSMckikdRJ8RGIkFa-X3xq3427tvM7J9adv8HP3Bzs\"\n```\n\nExample output:\n\n```shell\nekSMckikdRJ8RGIkFa-X3xq3427tvM7J9adv8HP3Bzs: Mined at block height 775810 with 22439 confirmations\n```\n\n```shell\n# Reprint the status every 10 seconds:\nwatch -n 10 ardrive tx-status -t \"ekSMckikdRJ8RGIkFa-X3xq3427tvM7J9adv8HP3Bzs\"\n```\n\n### Dealing With Network Congestion\n\nCurrently, Arweave blocks hold up to 1000 transactions per block. The \"mempool\", where pending transactions reside until they've been included into a block, will only hold a transaction for 50 blocks (~100-150 minutes) before it's discarded by the network resulting in no fees or data being transacted. During periods of network congestion (i.e. those where the mempool contains 1000 or more pending transactions), it may make sense to either:\n\na) wait for congestion to dissipate before attempting your transactions.\n\nb) apply the fee boost multiplier to your transactions rewards with the --boost parameter during write operations in order to front-run some of the congestion.\n\n#### Check for network congestion before uploading\u003ca id=\"check-congestion\"\u003e\u003c/a\u003e\n\n```shell\n# See all the transactions in the mempool\nardrive get-mempool\n\n# Return the count of the transactions in the mempool\nardrive get-mempool | jq 'length'\n```\n\n#### Front-run Congestion By Boosting Miner Rewards\u003ca id=\"boost\"\u003e\u003c/a\u003e\n\n```shell\n# Increase the miner reward on your transactions by 50%\nardrive upload-file --wallet-file /path/to/my/wallet.json --parent-folder-id \"f0c58c11-430c-4383-8e54-4d864cc7e927\" --local-path ./helloworld.txt --boost 1.5\n```\n\n#### Send AR Transactions From a Cold Wallet\u003ca id=\"cold-tx\"\u003e\u003c/a\u003e\n\nThe best cold wallet storage never exposes your seed phrase and/or private keys to the Internet or a compromised system interface. You can use the ArDrive CLI to facilitate cold storage and transfer of AR.\n\nIf you need a new cold AR wallet, generate one from an air-gapped machine capable of running the ArDrive CLI by following the instructions in the [Wallet Operations](#wallet-operations) section. Fund your cold wallet from whatever external sources you'd like. NOTE: Your cold wallet won't appear on chain until it has received AR.\n\nThe workflow to send the AR out from your cold wallet requires you to generate a signed transaction with your cold wallet on your air-gapped machine via the ArDrive CLI, and then to transfer the signed transaction (e.g. by a file on a clean thumb drive) to an Internet-connected machine and send the transaction to the network via the ArDrive CLI. You'll need two inputs from the Internet-connected machine:\n\n\u003cul\u003e\n\u003cli\u003ethe last transaction sent OUT from the cold wallet (or an empty string if none has ever been sent out)\u003c/li\u003e\n\u003cli\u003ethe base fee for an Arweave transaction (i.e. a zero bye transaction). Note that this value could change if a sufficient amount of time passes between the time you fetch this value, create the transaction, and send the transaction.\u003c/li\u003e\n\u003c/ul\u003e\n\nTo get the last transaction sent from your cold wallet, use the `last-tx` command and specify your wallet address e.g.:\n\n```\nardrive last-tx -a \u003cArweave address of cold wallet\u003e\n```\n\nTo get the base transaction reward required for an AR transaction, use the `base-reward` function, optionally applying a reward boost multiple if you're looking to front-run network congestion:\n\n```\nardrive base-reward --boost 1.5\n```\n\nWrite down or securely copy the values you derived from the Internet-connected machine and run the following commands on the airgapped machine, piping the outputted signed transaction data to a file in the process, e.g. `sendme.json` (if that's your signed transaction transfer medium preference):\n\n```\nardrive create-tx -w /path/to/wallet/file.json -d \u003cdest Arweave address\u003e -a \u003cAR amount to send\u003e --last-tx \u003cfrom previous steps\u003e --reward \"\u003cfrom previous steps\u003e\" \u003e sendme.json\n```\n\nTransport your signed transaction to the Internet-connected machine and run the following command to send your transaction to the Arweave network:\n\n```\nardrive send-tx -x /path/to/sendme.json\n```\n\n### Using a Custom Arweave Gateway\n\nOn each command that uses a gateway, it is possible to supply your own custom Arweave gateway using the flag `--gateway` or by setting an environment variable named `ARWEAVE_GATEWAY`.\n\nFor example, you could test out that your ArFS transactions are working as expected on a local test network such as [ArLocal] with this flow:\n\n```shell\n# Setup ArLocal instance on port 1984\nnpx arlocal\n\n# In another terminal, fund your wallet with AR\ncurl http://localhost:1984/mint/{ your public wallet address }/99999999999999\n\n# Create drive and root folder on ArLocal using `--gateway` flag\nardrive create-drive --gateway http://127.0.0.1:1984 -w /path/to/wallet -n 'my-test-drive'\n\n# Setup ARWEAVE_GATEWAY as ENV variable\nexport ARWEAVE_GATEWAY=\"http://localhost:1984\"\n\n# Mine block with drive + root folder transactions\ncurl \"$ARWEAVE_GATEWAY/mine\"\n\n# Upload file to ArLocal with ENV var\nardrive upload-file -F { root folder id from create drive } -l /path/to/file -w /path/to/wallet\n\n# Mine block with file transaction\ncurl \"$ARWEAVE_GATEWAY/mine\"\n\n# Inspect meta data of created entities\nardrive list-drive -d { drive id from create drive }\n\n# Download file to verify integrity\nardrive download-file -f { file id from upload file }\n```\n\n### Persistent Caching of ArFS Entity Metadata\u003ca id=\"metadata-caching\"\u003e\u003c/a\u003e\n\nTo avoid redundant requests to the Arweave network for immutable ArFS entity metadata, a persistent file cache is created and maintained at:\n\n```\nWindows: \u003cos.homedir()\u003e/ardrive-caches/metadata\nNon-Windows: \u003cos.homedir()\u003e/.ardrive/caches/metadata\n```\n\nThe `XDG_CACHE_HOME` environment variable is honored, where applicable, and will be used in place of `os.homedir()` in the scenarios described above.\n\nMetadata cache logging to stderr can be enabled by setting the `ARDRIVE_CACHE_LOG` environment variable to `1`.\n\nCache performance is UNDEFINED for multi-process scenarios, but is presumed to be generally usable.\n\nThe cache can be manually cleared safely at any time that any integrating app is not in operation.\n\n# All ArDrive CLI Commands\n\n```shell\n  █████╗ ██████╗ ██████╗ ██████╗ ██╗██╗   ██╗███████╗\n ██╔══██╗██╔══██╗██╔══██╗██╔══██╗██║██║   ██║██╔════╝\n ███████║██████╔╝██║  ██║██████╔╝██║██║   ██║█████╗\n ██╔══██║██╔══██╗██║  ██║██╔══██╗██║╚██╗ ██╔╝██╔══╝\n ██║  ██║██║  ██║██████╔╝██║  ██║██║ ╚████╔╝ ███████╗\n ╚═╝  ╚═╝╚═╝  ╚═╝╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═══╝  ╚══════╝\n                  ██████╗██╗     ██╗\n                 ██╔════╝██║     ██║\n                 ██║     ██║     ██║\n                 ██║     ██║     ██║\n                 ╚██████╗███████╗██║\n                  ╚═════╝╚══════╝╚═╝\n\n\nWrite ArFS\n===========\ncreate-drive\ncreate-folder\nupload-file\ncreate-manifest\n\nmove-file\nmove-folder\n\nretry-tx\n\n\nRead ArFS\n===========\nfile-info\nfolder-info\ndrive-info\n\nlist-folder\nlist-drive\nlist-all-drives\n\ndownload-file\ndownload-folder\ndownload-drive\n\nWallet Ops\n===========\ngenerate-seedphrase\ngenerate-wallet\n\nget-address\nget-balance\nsend-ar\n\nget-drive-key\nget-file-key\n\nlast-tx\n\n\nArweave Ops\n===========\nbase-reward\nget-mempool\ncreate-tx\nsend-tx\ntx-status\n\n# Learn more about a command:\nardrive \u003ccommand\u003e --help\n```\n\n# Getting Help\n\n[ArDrive Community Discord][ardrive-discord]\n\n[ardrive]: https://ardrive.io\n[arweave]: https://ardrive.io/what-is-arweave/\n[ardrive-github]: https://github.com/ardriveapp/\n[arfs]: https://ardrive.atlassian.net/l/c/m6P1vJDo\n[ardrive-web-app]: https://app.ardrive.io\n[ardrive-core]: https://github.com/ardriveapp/ardrive-core-js\n[yarn-install]: https://yarnpkg.com/getting-started/install\n[nvm-install]: https://github.com/nvm-sh/nvm#installing-and-updating\n[wsl-install]: https://code.visualstudio.com/docs/remote/wsl\n[editor-config-vscode]: https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig\n[prettier-vscode]: https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode\n[zipfs-vscode]: https://marketplace.visualstudio.com/items?itemName=arcanis.vscode-zipfs\n[eslint-vscode]: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint\n[viewblock blockchain explorer]: https://viewblock.io/arweave/\n[ardrive-discord]: https://discord.com/invite/ya4hf2H\n[arconnect]: https://arconnect.io/\n[kb-wallets]: https://ardrive.atlassian.net/l/c/FpK8FuoQ\n[arweave-manifests]: https://github.com/ArweaveTeam/arweave/wiki/Path-Manifests\n[example-manifest-webpage]: https://arweave.net/qozq9YIUPEHfZhoTp9DkBpJuA_KNULBnfLiMroj5pZI\n[arlocal]: https://github.com/textury/arlocal\n[mozilla-mime-types]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\n[viewblock]: https://viewblock.io/arweave/\n[tx_anchors]: https://docs.arweave.org/developers/server/http-api#field-definitions\n[gql-guide]: https://gql-guide.vercel.app/#owners\n[ardrive-turbo]: https://ardrive.io/turbo/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fardriveapp%2Fardrive-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fardriveapp%2Fardrive-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fardriveapp%2Fardrive-cli/lists"}