#arweave #cli

nightly bin+lib arloader

Command line application and library for uploading files to Arweave

17 releases

Uses new Rust 2021

new 0.1.25 Nov 30, 2021
0.1.24 Nov 24, 2021

#129 in Command line utilities

Download history 62/week @ 2021-11-02 36/week @ 2021-11-09 122/week @ 2021-11-16 115/week @ 2021-11-23

335 downloads per month

Apache-2.0

1MB
4K SLoC

crates.io build status docs.rs Crates.io

arloader

Command line application and library for effortlessly uploading files to Arweave. Arweave enables you to store documents and applications forever.

Upload gigabytes of files with one command specifying a glob pattern to match files against. Files are read and posted to arweave.net asynchronously and computationally intensive bundle preparation is performed in parallel across multiple threads.

Installation

  1. If you're on Linux, you can install the binary from the releases on github. Otherwise, of if you prefer, you can install from crates.io once you have rust installed.
cargo install arloader
  1. Get an Arweave wallet json file here.

  2. If you're going to use AR to pay for transactions, get AR tokens. I've been using gate.io despite the high withdrawal fees and KYC delays.

  3. If you're going to use SOL, get a Solana wallet json file and transfer some SOL to it.

Usage

If you're uploading more than one file, you should pretty much always be using bundles. Bundles take multiple files and packages them together in a single transaction. This is better than uploading multiple individual files because you only have to wait for one transaction to be confirmed. Once the bundle transaction is confirmed, all of your files will be available. Larger transactions with larger rewards are more attractive to miners, which means a larger bundled transaction is more likely to get written quickly than a bunch of smaller individual ones.

Arloader accepts file glob patterns and defaults to creating a bundle for your files.

Arloader will create as many bundles as necessary to upload all of your files. Your files are read asynchronously, bundled in parallel across multiple threads and then posted to arweave.net. Arloader support bundle sizes up to 200 MB, but the default bundle size is 10 MB, which makes it possible to post full bundle size payloads to the /tx endpoint instead of in 256 KB chunks to the /chunks endpoint. This should work fine for file sizes less than 10 MB. If your files sizes are bigger than 10 MB (but smaller than 200 MB), you can specify a larger bundle size with the --bundles-size argument - --bundle-size 100000000 to specify a size of 100 MB, for example.

  1. To get an estimate of the cost of uploading your files run
arloader estimate "<GLOB>"

Make sure to include quotes around your glob patterns, otherwise your shell will expand them into a list of files. Arloader expects a glob pattern, not a list of files.

  1. To upload your files run
arloader upload "<GLOB>" --log-dir "<LOG_DIR>"

This kicks off the process of uploading a stream of bundles created from your files. The default bundle size is 10 MB. The example output below had a bundle size of 5000 bytes.

bundle txid                                   items      KB  status       confirms
------------------------------------------------------------------------------------
 QGPFcZq91lQgmmz2l7rQHkSQpgfJi-Vhv47oTqIYLm4       2       3  Submitted           0
 _-bhdsi4irDEWz8R9wXT-1c06WVQVSMAmQxVF9OkW94       2       3  Submitted           0
 -OAWdFiGS4NKOZXVJG3yZ0yN4xydGOhfQGX2FCdlG88       2       3  Submitted           0
 UBWGFKyTrUVaCa7wi_181FjAd545vdoHmBQEdlaVdA4       2       3  Submitted           0
 qzQlASZrQXNF9HYIOTPjEZL9uy1U9Ou086kCkQWqld0       2       3  Submitted           0

A json status object gets written to LOG_DIR for each uploaded bundle with a file name of <TXID>.json. It has the transaction id, reward, creation time and ids and paths of the files included in the bundle.

{
    "id": "_-bhdsi4irDEWz8R9wXT-1c06WVQVSMAmQxVF9OkW94",
    "status": "Submitted",
    "file_paths": {
        "tests/fixtures/8.png": {
            "id": "0jd-NTQUZhmnKRY-kMt2vEcmSqgzKOLX_P3QYw6CaNE"
        },
        "tests/fixtures/9.png": {
            "id": "1XdiLkoZ5POHsNx7eLyRgisjnxTLzW8SxGsRcb22j84"
        }
    },
    "number_of_files": 2,
    "data_size": 3546,
    "created_at": "2021-11-23T05:47:41.948103600Z",
    "last_modified": "2021-11-23T05:47:41.948107100Z",
    "reward": 50947968
}
  1. After uploading your files, you'll want to check on their status to make sure the have been uploaded successfully and that they ultimately are confirmed at least 25 times before you can be absolutely certain they have been permanently uploaded.
arloader update-status --log-dir "<LOG_DIR>"

This will read the files in <LOG_DIR>, looking for a valid transaction id as a file stem, and then go out to the network to update the status of each. The example below contained two sets of bundles, one still pending and one with 45 confirmations.

bundle txid                                   items      KB  status       confirms
------------------------------------------------------------------------------------
 -OAWdFiGS4NKOZXVJG3yZ0yN4xydGOhfQGX2FCdlG88       2       3  Pending             0
 _-bhdsi4irDEWz8R9wXT-1c06WVQVSMAmQxVF9OkW94       2       3  Pending             0
 qzQlASZrQXNF9HYIOTPjEZL9uy1U9Ou086kCkQWqld0       2       3  Pending             0
 QGPFcZq91lQgmmz2l7rQHkSQpgfJi-Vhv47oTqIYLm4       2       3  Pending             0
 UBWGFKyTrUVaCa7wi_181FjAd545vdoHmBQEdlaVdA4       2       3  Pending             0
 KuuEZpbfCbw6izMeN3knWlpzmaFhnrDL9dUKCW2LQHw       2       3  Confirmed          45
 IRToYYvsftCiR71sfW5qt8XCzBFotwoDFBoEMEtrMrU       2       3  Confirmed          45
 M2QZYxUqw3ZJ2KXzU4pfw9fFIkVOSrJbSpE7NAvHLvo       2       3  Confirmed          45
 qvci4i6Mfr-5_NHI1bL-Omv16QEUw3iiirzv4fXefnM       2       3  Confirmed          45
 NAP2vTKQdMG_eKyKBYz3876T4yBFl4oYFYqwwwnHbFA       2       3  Confirmed          45
  1. Once you have a sufficient number of confirmations of your files, you may want to create a manifest file, which is used by the Arweave gateways to provide relative paths to your files. In order to do that, you run
arloader upload-manifest --log-dir "<LOG_DIR>"

where <LOG_DIR> is the directory containing your bundle status json files. This will go through and consolidate the paths from each of the bundles, create a consolidated manifest, upload it to Arweave and then write a file named manifest_<TXID>.jsonto <LOG_DIR>. Once the transaction uploading the manifest has been confirmed, you will be able to access your files and both https://arweave.net/<BUNDLE_ITEM_ID> and https://arweave.net<MANIFEST_ID>/<FILE_PATH> where MANIFEST_ID is the id of the manifest transaction and FILE_PATH is the relative path of the file included in the GLOB pattern you specified with the upload command.

{
    "tests/fixtures/0.png": {
        "id": "NNdSluho1hHrlrVdoFLlx6K37XxArSaafDRchaRk-4k",
        "id_url": "https://arweave.net/NNdSluho1hHrlrVdoFLlx6K37XxArSaafDRchaRk-4k",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/0.png"
    },
    "tests/fixtures/1.png": {
        "id": "eGZUfB2HmzOO8kOf1VKD9VC6eJBQHWYezfuJ1u2QwgA",
        "id_url": "https://arweave.net/eGZUfB2HmzOO8kOf1VKD9VC6eJBQHWYezfuJ1u2QwgA",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/1.png"
    },
    "tests/fixtures/2.png": {
        "id": "yKpDmxwZq2Hd0RPU7x9FYguu7uAH2yFFKYdafr2oQDQ",
        "id_url": "https://arweave.net/yKpDmxwZq2Hd0RPU7x9FYguu7uAH2yFFKYdafr2oQDQ",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/2.png"
    },
    "tests/fixtures/3.png": {
        "id": "LA6Lbi8Smy1NlY1ZEQg6oHuz7tHS3aqipjTQ6IYYvx4",
        "id_url": "https://arweave.net/LA6Lbi8Smy1NlY1ZEQg6oHuz7tHS3aqipjTQ6IYYvx4",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/3.png"
    },
    "tests/fixtures/4.png": {
        "id": "Q_8X5bYAHWwAKiVxc68gyLOalmVy2M1WuzmN_VIsa9k",
        "id_url": "https://arweave.net/Q_8X5bYAHWwAKiVxc68gyLOalmVy2M1WuzmN_VIsa9k",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/4.png"
    },
    "tests/fixtures/5.png": {
        "id": "DukqezWt4nO5TXhIkI8_C2S-IgvCRlMqoCaoQJqDvsc",
        "id_url": "https://arweave.net/DukqezWt4nO5TXhIkI8_C2S-IgvCRlMqoCaoQJqDvsc",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/5.png"
    },
    "tests/fixtures/6.png": {
        "id": "s0SrsnAIrXIq320gi5zXlFv2mRvsOlY6KTFxexQ0uiY",
        "id_url": "https://arweave.net/s0SrsnAIrXIq320gi5zXlFv2mRvsOlY6KTFxexQ0uiY",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/6.png"
    },
    "tests/fixtures/7.png": {
        "id": "wcnez7bz7xZzlr18Wqhh0YsdQ7uLpx2HCqClvRVKBV0",
        "id_url": "https://arweave.net/wcnez7bz7xZzlr18Wqhh0YsdQ7uLpx2HCqClvRVKBV0",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/7.png"
    },
    "tests/fixtures/8.png": {
        "id": "dRuhwEu7XtY3GGAVurr9-4W-ol-pKZ3J3Ctsv9XwAYM",
        "id_url": "https://arweave.net/dRuhwEu7XtY3GGAVurr9-4W-ol-pKZ3J3Ctsv9XwAYM",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/8.png"
    },
    "tests/fixtures/9.png": {
        "id": "dBrDK_pPcU06vkmWJfQ-4tYAE7eS1undBjLW9jS-CTE",
        "id_url": "https://arweave.net/dBrDK_pPcU06vkmWJfQ-4tYAE7eS1undBjLW9jS-CTE",
        "relative_url": "https://arweave.net/qR1DG8KphkbpiQqy2VCfy6cBfHuXahXV9UR9--zDc3w/tests/fixtures/9.png"
    }
}

You can run the following command to get an update on the status of your manifest transaction.

arloader get-status `<MANIFEST_ID>`

Usage with SOL

You can use SOL to pay for your transactions without going through the hassle of procuring AR tokens.

Arloader usage is pretty much exactly the same as above, with the addition of the --with-sol flag.

  1. To get an estimate of the cost of uploading your files run
arloader estimate "<GLOB>" --with-sol
  1. To upload your files run
arloader upload "<GLOB>" --log-dir "<LOG_DIR>" --with sol

This will create the same stream of bundles that gets created without using SOL and then goes out to an api to get your transactions signed. Once the SOL payment transaction has gone through, the signature comes back from the api and gets added to your bundle transaction. Then the transaction gets uploaded directly to the arweave.net gateway from your computer.

Reward Multiplier

Arweave is limited to approximately 1,000 transactions every two minutes so if you happen to submit your transaction at a time when there are a lot of pending transactions, it may take longer to get written, or if there are enough more attractive transaction, i.e, with higher rewards, it may not get written at all. To check the current number of pending transactions, run

arloader pending

and that will print the number of pending transactions every second for one minute.

 pending tx
-------------------------------------------------------------------------------------------------
  118 | ▥▥▥
  123 | ▥▥▥
  124 | ▥▥▥
  224 | ▥▥▥▥▥
  125 | ▥▥▥
  326 | ▥▥▥▥▥▥▥
  128 | ▥▥▥

Given that Arloader bundles by default, your transaction is hopefully relatively attractive and you don't need to increase the reward to get it written in a timely fashion. However, if you see that there are a lot of transactions pending and you want to be sure your transaction goes through quickly, you can adjust the reward with --reward-multiplier followed by something tha can be parsed as a float between 0.0 and 10.0. The reward included in your transaction will then be multiplied by this factor when it gets submitted. Similar to the --with-sol flag, you can add --reward-multiplier to both estimate and upload commands.

Usage without Bundles

You can add the --no-bundle flag if for some reason you want to create individual transactions. This works with both estimate and upload commands. In that case individual status objects are written to LOG_DIR and you can run update-status to update them from the network and status-report for a count of transactions by status.

Dependencies

~28MB
~628K SLoC