Python3 CLI tool for interacting with Filecoin PoRep Market smart contracts
using Click, Web3 and psycopg.
Developed for admins, clients, and SPs to manage their market interactions from command line.
Use python >= 3.10
python3 --version # check your python version
git clone https://github.com/fidlabs/filecoin-porep-market-tooling && cd filecoin-porep-market-tooling # clone the repo
python3 -m pip install -r requirements.txt # install dependencies
cp .env.mainnet .env # create your local .env file
chmod 600 .env # optional, but recommended for security: restrict access to the .env fileMake sure you have the required environment variables set (see .env).
Run the script: python3 ./porep_tooling_cli.py and follow help prompts.
- The app does not store any state locally - all state is retrieved from the blockchain by design.
- The app stores all blockchain transaction logs to
logs/. - Default behaviour is to wait for each transaction to succeed after sending it.
- The app operates on FEVM smart contracts (thus EVM 0x-addresses) but fully supports Filecoin f-addresses / Actor IDs with proper conversion.
- There are multiple ways of providing the user's private key for blockchain transactions and the priority is as follows:
[ADMIN|CLIENT|SP]_PRIVATE_KEYvariable in the system environment variables or in the local.envfile,[ADMIN|CLIENT|SP]_LOTUS_WALLETand[ADMIN|CLIENT|SP]_LOTUS_TOKENvariables when using Lotus wallet,- if non of those are set, the app will prompt the user to input the private key for required operations in a secure manner.
- Read-only commands do not require private key / lotus wallet set, though some of them require user's address (
client --addressandsp --organization). - Rule of thumb: the private key / lotus wallet you set is the one that signs and sends transactions,
so always use the one with correct permissions / approvals / rights for the transaction you want to send. - Make sure the address for blockchain transactions you use has enough FIL for gas fees and is initialized on the Filecoin network.
- The app prints output of read-only commands in json format to be easily parsable by other tools.
- PoRep Market smart contracts supports only 32 GiB sectors.
- PoRep Market smart contracts assumes a month is always 30 days.
- All blockchain transactions require manual user confirmation before sending. There is no option to override this.
If you decline the final confirmation, the command falls back to dry-run behavior without broadcasting the transaction. - The app runs locally and does not transmit any data to external servers besides blockchain.
All interactions are between the user's machine and the provided
RPC_URLblockchain. - The app does not log any sensitive information to the console or to the log files. All transaction logs are stored without any sensitive information.
- When using Lotus wallet for blockchain transaction signing, the private key never leaves the Lotus wallet and is not exposed to the CLI app.
This is the recommended way of using the app.
Existing V1 deals move to V2 without resealing: the client attaches the V1 DataCap claims to a new V2 deal, the SP extends the sectors, and the client closes the V1 payment rail. Follow the runbooks:
Set POREP_MARKET_V1 and POREP_MARKET_V1_CHAIN_ID (both already in .env.mainnet) and, for SPs, SP_ORGANIZATION.
The client must run init-deal and adopt the claims before the NV29 network upgrade (epoch 6470279, 2026-10-19 12:59 UTC).
Anyone can check progress without a wallet with migration-status.
client adopt-v1-claims asks once for all the batches it lists instead of once per transaction;
--print-only shows the plan without loading a signer.
-
Follow the Installation steps.
-
Steps 3-5 below are required for SP to make blockchain write transactions (such as
sp register-offer). You won't need this in a typical SP flow. -
IMPORTANT: interaction with the chain requires the private key for the message sender, so for security do not use your miner wallet for sending commands to the PoRep Market.
Instead, you will need to create a miner controller wallet. If you already have one and want to reuse it, that’s fine.
However, to follow best security practices, we recommend you create a new wallet and register it as a controller wallet for all the miners you will be using in the PoRep Market.
The PoRep Market then uses controller status to verify that the command sender is authorised to send commands on behalf of your miner.
Follow the steps here: https://lotus.filecoin.io/storage-providers/operate/addresses/#control-addresses -
Export the private key of your newly created wallet:
lotus wallet export <your-controller-address> | xxd -r -p | jq -r '.PrivateKey' | base64 -d | xxd -p -c 32 | sed 's/^/0x/'
And set it as
SP_PRIVATE_KEYin your.envfile. The value you store there must be this exported private key in 32-byte hex format with a0xprefix - not the wallet address you pass tolotus wallet export -
Alternatively, generate an auth token for your controller address and use it instead of the private key:
lotus auth create-token --perm sign --wallet <your-controller-address>
And set it as
SP_LOTUS_TOKENin your.envfile alongsideSP_LOTUS_WALLETwith the address of your controller wallet.
Using this method, the private key never leaves the Lotus wallet and is not exposed to the CLI app. You must use f410 address or standard EVM address for this method. -
Set your SP organization address in
.env:# Organization address to manage SPs from # You must have the SP_PRIVATE_KEY of an organization controlling address set to perform SP management operations SP_ORGANIZATION=<your-controller-address>
-
Optional, but very useful for downloading the deal data: install
aria2:- on Mac
brew install aria2 - on Debian/Ubuntu:
sudo apt install aria2 - on Arch:
sudo pacman -S aria2
- on Mac
-
Now you should be ready to run the tools.
-
to find deals allocated to you and ready to download / onboard:
python3 ./porep_tooling_cli.py sp get-deals ACTIVE
-
to download / onboard the deal that is allocated to you:
python3 ./porep_tooling_cli.py sp onboard-data <deal-id> --output-dir <dir-to-download-to>
-
get the deal allocation IDs:
python3 ./porep_tooling_cli.py sp get-allocations <deal-id>
-
and claim allocations for a deal:
python3 ./porep_tooling_cli.py sp claim-allocations {curio|boost} <deal-id>
-
-
For deals using the
SECTOR_PLACEMENTevidence adapter there are no allocations to claim. Instead, each deal piece must be sealed with a FIP-0109 notification sent to the deal's evidence adapter, withrequire_notification_successset totrue. Get the notification address and payload for each piece with:python3 ./porep_tooling_cli.py sp get-piece-notifications <deal-id>
-
To get the full list of commands for the tooling:
python3 ./porep_tooling_cli.py sp --help
-
Follow the Installation steps.
-
Put your client keys in the
.envfile:# Use `lotus wallet list` to see your wallets and their addresses and `lotus wallet new delegated` to create new delegated wallet # Must be delegated f410 address or standard EVM address CLIENT_LOTUS_WALLET=<lotus-wallet> # Generate this by running `lotus auth create-token --perm sign` CLIENT_LOTUS_TOKEN=<lotus-token>
or
# 32-byte raw private key (hex, 0x-prefixed) CLIENT_PRIVATE_KEY=<private key>
-
Prepare your dataset with Singularity (or equivalent) so you have a published manifest URL and piece CARs served for the SP to fetch.
-
Propose a deal from that manifest. Deals can be public (open retrieval) or private (retrieval limited to the deal owner and any wallets you later authorize with a voucher):
python3 ./porep_tooling_cli.py client propose-deal <manifest-url> \ --price-per-tib-per-month <usdc-in-decimal-format> \ --duration-months <months> \ --retrievability-pct <pct> \ --bandwidth-mbps <mbps> \ --latency-ms <ms> \ --indexing-pct <pct> \ --deal-type <public|private>
-
Initialize payment (validator, deposit, rail):
python3 ./porep_tooling_cli.py client init-deal <deal-id>
-
Make DataCap allocations:
python3 ./porep_tooling_cli.py client make-allocations <deal-id>
This step applies only to DataCap evidence deals. New deals use the PoRep Market global evidence adapter, check it with
client info. When it isSECTOR_PLACEMENT,client propose-dealcommits to the manifest piece set instead of hashing the manifest file, no DataCap allocations are needed and the Storage Provider proves the data placement directly when sealing (seesp get-piece-notifications). Go straight toclient deposit-for-deals <deal-id>. -
Optional - for a private deal, sign an EIP-712 retrieval voucher so a third-party wallet can retrieve the data (used with large-paid-retrievals):
python3 ./porep_tooling_cli.py client sign-retrieval-voucher \ --grantee <0x-third-party-wallet> \ --scope <DEAL_ID>
Prints a long-lived standalone
RetrievalVouchertoken (grantee,scope,issuedAt,deadline, embeddedsignature) forAuthorization: RetrievalVoucher.
Clients mint a per-pieceRetrievalProofand send it asAuthorization: RetrievalProof— see access-vouchers-eip712.
--deal-idis accepted as an alias for--scope.
- See files in
cli/commandsfor examples of how to implement new commands. - Keep the code clean and simple, follow the existing patterns and best practices.
- Use
Exception(ValueError,RuntimeError, ...) for internal-like errors (things that "should not happen") andclick.ClickExceptionfor user-like errors (things that happens "because of the user"). - Use
click.echofor all user-facing output andloggerfor file logging. - For read-only commands, print the output in json format for easy parsing by other tools.