cardano-mass-payments 0.1.5
A tool for handling mass payments for Cardano (ADA)
Requires Python: >=3.7

# Cardano Mass Payments


---------------------



Cardano Mass Payments is a Cardano python package that automates and optimizes the sending of large numbers of transactions using a single command.



### Table of contents



*   [Requirements](#requirements)
*   [Installation](#installation)
*   [Features](#features)
*   [Package Usage](#package-usage)
    *   [Parameter Details](#parameter-details)
    *   [Flag Details](#flag-details)
    *   [Example Command](#example-command)
*   [Code for Transaction Plan Generation](#code-for-transaction-plan-generation)
*   [Code for Mass Payments Script Generation](#code-for-mass-payments-script-generation)
*   [Algorithm](#algorithm)
*   [Possible Errors](#possible-errors)



### Requirements



The package can only be run on `python >= 3.7`.

These are the minimum required versions of the required tools:

*   `pycardano >= 0.7.0`

Currently, all Script methods requires the following cardano tools:
- Cardano Node: `>=1.35.5`


### Installation



Install the library using [pip](https://pip.pypa.io/en/stable/):



```plain
pip install cardano-mass-payments
```



### Features

*   **Can be used as a Python script** - Mass Payments Script can be generated just by calling the `cardano-mass-payments-generate` command.
*   **Can be used as a Python library** - Mass Payments Script can be generated by incorporating the `cardano-mass-payments` library in your python code.
*   **Fee optimization** - The library groups the payments into transaction groups, making fees significantly less than the total fees when sending these payments individually.
*   **Support for both Cardano CLI and PyCardano** - Currently, `cardano-mass-payments` supports communication to Cardano via `cardano-cli` and `pycardano`
*   **Transaction plan generation** - Alongside the scripts, `cardano-mass-payments` also includes generation of a file which contains the final and adjusted transaction plan which will be the basis of the mass payments script. The script also includes commands that update the transaction plan file.
*   **Can recover and continue in case of an error during execution** - Whenever an error is encountered in the script, the library can create an updated script using the updated transaction plan file (which skips already submitted transactions) and can go straight to pending transactions.
*   **Support for custom metadata and messages to be included in the transactions** - Cardano Metadata is supported and Transaction Messages will be automatically fixed by the script to satisfy Cardano's policy regarding transaction messages.
*   **Structured JSON output** - With JSON Output Type, script output will be on a structured JSON format, from the final output, to the error messages as well.
*   **Dust collection** - Allows for handling Input UTxOs with less than a specified amount (dust) and combining them into one Input UTxO.
*   **Immediate execution** - Allows for automatically executing the newly generated script from the `cardano-mass-payments-generate` command.



### Package Usage


#### Parameter Details


| **Parameter**                 | **Description**                                                                                                                                                                                                                                                                                                                                                                                   |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `--cardano-network`           | Dictates which Cardano network the package will connect to.<br>Possible values:<br>\- `MAINNET`<br>\- `TESTNET`                                                                                                                                                                                                                                                                                   |
| `--script-method`             | Dictates which method to use for handling the internal logic (getting protocol parameters, getting user utxos).<br>Possible values:<br>\- `HOST_CLI` - connects package to the Cardano CLI installed in the machine<br>\- `DOCKER_CLI` - connects package to the Cardano CLI Docker Image<br>\- `PYCARDANO` - uses Pycardano in the package                                                       |
| `--output-type`               | Dictates the type of the generated output.<br>Possible values:<br>\- `BASH_SCRIPT` - Creates a bash file and displays the file name in the console<br>\- `CONSOLE` - Displays the script contents in console<br>\- `JSON` - Display a JSON object in console containing the script file name<br>\- `TRANSACTION_PLAN` - Only create the transaction plan and display the file name in the console |
| `--sources-csv`               | CSV File containing the source address details<br>Format per line:<br>`<source_address>,<signing_key_file_of_address_1>,<signing_key_file_of_address_2>,...,<signing_key_file_of_address_n>`                                                                                                                                                                                                      |
| `--payments-csv`              | CSV File containing the payment details that will be sent to Cardano.<br>Format per line:<br>`<destination_address>,<amount_in_lovelace>`                                                                                                                                                                                                                                                         |
| `--allowed-ttl-slots`         | Number of slots allowed before the transaction to be deemed invalid.<br>Default: `1000`                                                                                                                                                                                                                                                                                                           |
| `--dust-collection-method`    | Method used for dust collection.<br>Possible values:<br>\- `COLLECT_TO_SOURCE` - dust will all be collected and sent to the primary source address<br>\- `COLLECT_PER_ADDRESS` - dust will be collected and sent per address                                                                                                                                                                      |
| `--dust-collection-threshold` | Allowable amount in lovelace that will be used for checking if the transaction is deemed as a dust.<br>Default: `10000000`                                                                                                                                                                                                                                                                        |
| `--source-address`            | Primary Source Address (should be in the `--sources-csv` file). If not provided, will use the first address in the `--sources-csv` file.                                                                                                                                                                                                                                                          |
| `--source-signing-key-file`   | Signing Key File of Primary Source Address. If not provided, will use the corresponding signing key file of the primary source address in the `--sources-csv` file.                                                                                                                                                                                                                               |
| `--metadata-json-file`        | JSON File containing the metadata template that will be included in the cardano transaction.                                                                                                                                                                                                                                                                                                      |
| `--metadata-message-file`     | TXT File containing the message that will be added in the transaction metadata.                                                                                                                                                                                                                                                                                                                   |
| `--transaction-plan-file`     | TXT Transaction Plan File which can be used to generate the script.                                                                                                                                                                                                                                                                                                                               |
| `--magic-number`              | Cardano Network Magic Number where the python script will connect to.                                                                                                                                                                                                                                                                                                                             |
| `--cardano-node-docker-image` | Docker Image name of the Cardano node.                                                                                                                                                                                                                                                                                                                                                            |
| `--reward-withdrawal-amount`  | Amount of lovelace that will be withdrawn from the source's rewards                                                                                                                                                                                                                                                                                                                               |

#### Flag Details



| **Flag**                         | **Description**                                                                                                         |
|----------------------------------|-------------------------------------------------------------------------------------------------------------------------|
| `--add-comments`                 | Add comments in the generated bash script                                                                               |
| `--use-docker-cli-for-pycardano` | By default, Pycardano connects to Cardano CLI. This flag is used if the connected cli is the host one or the docker one |
| `--enable-dust-collection`       | Enable Dust Collection (Additional Step of combining small utxos into 1 utxo)                                           |
| `--execute-script-now`           | Execute the script right after it's generated                                                                           |
| `--include-rewards`              | Withdraw rewards of source address and include it in the transaction                                                    |



#### Example Command



```plain
cardano-mass-payments-generate --sources-csv source.csv --payments-csv payments.csv --cardano-network TESTNET
--add-comments --output-type BASH_SCRIPT --metadata-message-file metadata.txt --metadata-json-file metadata.json
--execute-script-now --enable-dust-collection --script-method PYCARDANO --use-docker-cli-for-pycardano
```



### Code for Transaction Plan Generation



Using the python package, we can generate the transaction plan object and save it in as a json file



```plain
from cardano_mass_payments.masspayments import generate_transaction_plan
from cardano_mass_payments.constants.common import (
    ScriptOutputFormats,
    CardanoNetwork,
    ScriptMethod,
    DustCollectionMethod,
)

transaction_plan = generate_transaction_plan(
    output_format=ScriptOutputFormats.BASH_SCRIPT,
    source_address="test_source_address",
    source_details={
        "test_source_address": "test_signing_key_file"
    },
    payments_csv_file="payments.csv",
    cardano_network=CardanoNetwork.TESTNET,
    script_method=ScriptMethod.METHOD_DOCKER_CLI,
    allowed_ttl_slots=1000,
    dust_collection_method=DustCollectionMethod.COLLECT_TO_SOURCE,
    dust_collection_threshold=10000000,
    enable_dust_collection=True,
)
with open("transaction_plan_filename", "w+") as transaction_plan_file:
    transaction_plan_file.write(transaction_plan.json())
```



### Code for Mass Payments Script Generation



Using the python package, we can also generate the mass payments script



```plain
from cardano_mass_payments.masspayments import generate_bash_script
from cardano_mass_payments.constants.common import (
    CardanoNetwork,
    ScriptMethod,
)

bash_script_result = generate_bash_script(
    transaction_plan=transaction_plan,  # Generated transaction plan from generate_transaction_plan
    source_details={
        "test_source_address": "test_signing_key_file"
    },
    source_address="test_source_address",
    metadata_file="metadata.json",
    allow_ttl_slots=1000,
    add_comments=True,
    store_in_file=False,
    network=CardanoNetwork.TESTNET,
    method=ScriptMethod.METHOD_DOCKER_CLI,
)
```



### Algorithm

1.  Parse the source and payment CSV files.
2.  If `--transaction-plan-file` is provided, parse the transaction plan file.
3.  Else, generate a transaction plan based on the parsed source and payment details.
    1.  Create the initial transaction plan setup.
        1.  Check the initial transaction byte size of the possible payment group UTxO (1 input, n payments).
        2.  If the transaction size is greater than the maximum, adjust the number of payments until the transaction size satisfies the size check.
        3.  Divide the payments into k groups with n (obtained from step `3.1.2`) payments.
        4.  Select Input UTxOs that can satisfy the total transaction amounts and fees.
        5.  Create a mock transaction with the selected input utxos and payments based on the payment groups + 1 payment utxo for the change.
        6.  Get the size of the mock transaction. This will determine if dust collection is required or not.
            1.  If it's greater than the maximum, dust collection is required.
    2.  Dust Collection Step
        1.  While all selected input utxos are not yet used,
            1.  Select Input UTxOs that can satisfy the maximum transaction byte size
                1.  n inputs, 1 payment for 1st group
                2.  n+1 inputs, 1 payment for the remaining groups (the additional input is the input utxo from the previous dust group)
            2.  Create a Dust Group with the selected inputs
    3.  Adjust UTxO Step
        1.  Classify the payment groups on whether their transaction size is above/below the maximum transaction size.
        2.  For those above the maximum,
            1.  Remove payments until transaction satisfy the maximum size.
            2.  Move the removed payments in a temporary list.
        3.  For those below the maximum,
            1.  Get payments from the temporary list and add them until transaction doesn't satisfy the maximum size.
        4.  If there are payments in the temporary list,
            1.  If the preparation transaction size is less than the maximum, add payments until transaction doesn't satisfy the maximum size.
        5.  If there are remaining payments in the temporary list, treat them as a new payment group.
    4.  Generate the transaction plan using the adjusted details obtained in step `3.3`.
4.  Create a transaction plan file from the generated transaction plan.
5.  If `--output-type` is `TRANSACTION_PLAN`, return the transaction plan filename.
6.  Else, create a bash script from the transaction plan and print the corresponding `--output-type`.
    *   `BASH_SCRIPT` - Display the file name in the console.
    *   `CONSOLE` - Displays the script contents in console.
    *   `JSON` - Display a JSON object in console containing the script file name.
7.  If `--execute-script-now`,
    1.  Display transaction plan details.
        *   Transaction Plan Filename
        *   Number of Dust Transactions to be Generated
        *   Number of Payment Transaction Groups Generated
        *   Total Amount Required
        *   Expected Maximum Change Returned
    2.  A prompt will be displayed asking the user to review the plan and asks to continue with the execution.
    3.  Repeat asking for input if the user inputs any value other than yes/no.
    4.  If yes, execute the script.
    5.  If no, a "Thank You" message will be displayed.



### Possible Errors



| **Error**                     | **JSON Output**                                                                                                                                                                            | **Description**                                                                                                                                           |
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| <br>`ScriptError`<br>         | {<br> &emsp;"code": 500001,<br> &emsp;"message": STR,<br> &emsp;"context": DICT<br>}                                                                                                       | Unexpected Errors encountered during any part of the mass payments script generation                                                                      |
| <br>`InsufficientBalance`<br> | {<br> &emsp;"code": 400001,<br> &emsp;"message": STR,<br> &emsp;"context": {<br> &emsp; &emsp;"required\_amount": INT,<br> &emsp; &emsp;"current\_amount": INT<br> &emsp;}<br>}            | Current Balance doesn't satisfy the total transaction amount and fee required for submission                                                              |
| <br>`InvalidMethod`<br>       | {<br> &emsp;"code": 400002,<br> &emsp;"message": "Invalid Method",<br> &emsp;"context": {<br> &emsp; &emsp;"allowed\_methods": STR\[\],<br> &emsp; &emsp;"method": STR<br> &emsp;}<br>}    | Method is not included in the allowed methods. This will show on invalid command argument value.                                                          |
| <br>`InvalidNetwork`<br>      | {<br> &emsp;"code": 400003,<br> &emsp;"message": "Invalid Network",<br> &emsp;"context": {<br> &emsp; &emsp;"allowed\_networks": STR\[\],<br> &emsp; &emsp;"network": STR<br> &emsp;}<br>} | Network is not included in the allowed networks. This will show on invalid command argument value.                                                        |
| <br>`InvalidFileError`<br>    | {<br> &emsp;"code": 400004,<br> &emsp;"message": STR,<br> &emsp;"context": {<br> &emsp; &emsp;"file":STR<br> &emsp;}<br>}                                                                  | Unexpected Errors encountered while doing file related function (Source and Payment CSV Files, Signing Key Files, Metadata Files, Transaction Plan Files) |
| <br>`InvalidType`<br>         | {<br> &emsp;"code": 400005,<br> &emsp;"message": STR,<br> &emsp;"context": {<br> &emsp; &emsp;"type":STR<br> &emsp;}<br>}                                                                  | Value Type doesn't match with the required field type. This will show on invalid command argument values.                                                 |
| <br>`EmptyList`<br>           | {<br> &emsp;"code": 400006,<br> &emsp;"message": STR<br>}                                                                                                                                  | List is empty.                                                                                                                                            |