This repository provides a command-line interface (CLI) called Wrapped Deal that aims to offer trustless automated payments to Storage Providers (SPs) for Filecoin deal services. By using the MarketDealWrapper smart contract, clients can automate fund transfers to SPs whenever a deal is made, eliminating the need for manual payment arrangements.
- Introduction
- Architecture Overview
- Prerequisites
- Setup
- CLI Usage Guide
- Deal Making Flow Using Wrapped Deal
- IMPORTANT NOTES
- Additional Resources
Wrapped Deal is designed to streamline and secure the payment process between Filecoin clients and Storage Providers:
- Offers an on-chain mechanism to handle payments, ensuring trustless transactions.
- Provides a set of commands to read and write data to the MarketDealWrapper smart contract.
- Integrates with the Filecoin network using tools such as Foundry and Boost.
The Wrapped Deal CLI interacts with the MarketDealWrapper smart contract to automate payments for Filecoin deals. The flow looks like this:
graph TD
A[Deploy MarketDealWrapper Contract] --> B[Add Storage Provider with Payment Token and Address]
B --> C[Whitelist f1 Address in Contract]
C --> D[Approve and Add Tokens for SP Payment]
D --> E[Make Boost Deal using Whitelisted Address]
subgraph Market_Actor_Calls[Market Actor Callbacks]
subgraph Notify[deal_notify]
F[Initialize Payment Schedule to SP]
end
subgraph Auth[authenticate_message]
H[Verify Signature]
end
end
E --> Market_Actor_Calls
Market_Actor_Calls --> J[SP Requests Payment Withdrawal]
J --> K{Check if Deal is Live}
K -->|Yes| L[Release Payment Based on Epochs Passed]
K -->|No| M[Pay Only for Maintained Period]
style A fill:#e1f5fe
style E fill:#e8f5e9
style Market_Actor_Calls fill:#fff3e0, color:#000000
style Auth fill:#ffe0b2, color:#000000
style Notify fill:#ffe0b2, color:#000000
style K fill:#fce4ec
-
Foundry
- Used to build and deploy the MarketDealWrapper contract.
- Install via:
curl -L https://foundry.paradigm.xyz | bash foundryup
- Refer to the official Foundry documentation for detailed instructions.
-
Boost
- Allows you to make deals on the Filecoin network.
- Refer to Boost’s official documentation for setup and usage details.
-
Boost Wallet
- Ensure you have a funded wallet set in boost to make deals on the Filecoin network.
- If not set you can set it with the following command:
boost wallet new
- Refer to the Boost Wallet documentation for more information.
-
Go (1.22.x recommended)
- Verify with:
go version
- If needed, install or update from golang.org.
- Verify with:
Use Git to clone this repository:
git clone https://github.com/your-organization/fil-deal-wrapper.git
cd fil-deal-wrapper
Inside the project’s go.mod file, a replace directive is used to point to a local build of filecoin-ffi
Replace the path with the local path on your machine where filecoin-ffi is located. For example:
replace github.com/filecoin-project/filecoin-ffi => /path/to/your/boost/extern/filecoin-ffi
-
Enter the contracts directory (or wherever your Foundry project is located):
cd contracts
-
Build the MarketDealWrapper contract:
forge build
-
Deploy the contract to a desired network (e.g., Anvil, testnet, or mainnet):
forge create --rpc-url <YOUR_RPC_URL> --private-key <YOUR_PRIVATE_KEY> src/MarketDealWrapper.sol:MarketDealWrapper
Make sure to replace
<YOUR_RPC_URL>
and<YOUR_PRIVATE_KEY>
with actual values. -
Note the contract address displayed after deployment, as you will need it to interact with the contract using the CLI.
-
Return to the root directory of the project:
cd ..
-
Set the environment variable for CLI to avoid putting some flags every time:
PRIVATE_KEY
RPC_URL
FULL_NODE_API_INFO
- https://api.calibration.node.glif.io/rpc/v1 for calibration network
If you want to make local deals directly with files in your environment you will need:
LIGHTHOUSE_API_KEY
-
Build the Wrapped Deal CLI:
go build -o wrappedeal
This produces an executable called wrappedeal in your current directory.
Once built, run the CLI with:
./wrappedeal help
OR
wrappedeal help
Below are the main commands and subcommands available in wrappedeal, along with examples on how to use them. Ensure that all flags are specified before the parameters. Do see IMPORTANT NOTES at the end to avoid common pitfalls.
Use fil
for Filecoin-related tasks.
wrappedeal fil [subcommand] [flags]
-
deal
Make an online deal with a CAR file.wrappedeal fil deal \ --http-url "<HTTP_URL>" \ --car-size <SIZE> \ --provider "<SP_ADDRESS>" \ --commp "<COMM_P>" \ --piece-size <PIECE_SIZE> \ --payload-cid "<CID>" \ --contract "<CONTRACT_ADDRESS>"
-
local-deal
Make a deal from a local file or folder.wrappedeal fil local-deal \ --path "<FILE_OR_FOLDER_PATH>" \ --provider "<SP_ADDRESS>" \ --contract "<CONTRACT_ADDRESS>" --lighthouse true # optional
-
offline-deal
Make an offline deal (the CAR is provided out-of-band).wrappedeal fil offline-deal \ --provider "<SP_ADDRESS>" \ --commp "<COMM_P>" \ --piece-size <PIECE_SIZE> \ --payload-cid "<CID>" \ --contract "<CONTRACT_ADDRESS>"
-
get-eth-addr
Get the Ethereum address corresponding to a Filecoin address.wrappedeal fil get-eth-addr \ --filecoin-addr "<FILECOIN_ADDRESS>" \
-
get-actor-id
Retrieve the Actor ID from a Filecoin address.wrappedeal fil get-actor-id \ --filecoin-addr "<FILECOIN_ADDRESS>" \
Use write-contract
to send write transactions to the MarketDealWrapper contract.
wrappedeal write-contract [subcommand] [flags] [parameters]
-
add-sp
Add a storage provider to the MarketDealWrapper contract.wrappedeal write-contract add-sp \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ --actor-id <ACTOR_ID> \ --eth-addr "<ETH_ADDRESS>" \ --token "<TOKEN_ADDRESS>" \ --price-per-tb-per-month <PRICE>
-
update-sp
Update a storage provider in the MarketDealWrapper contract.wrappedeal write-contract update-sp \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ --actor-id <ACTOR_ID> \ --eth-addr "<NEW_ETH_ADDRESS>" \ --token "<NEW_TOKEN_ADDRESS>" \ --price-per-tb-per-month <NEW_PRICE>
-
add-to-whitelist
Add an Actor ID to the whitelist in the MarketDealWrapper contract.wrappedeal write-contract add-to-whitelist \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ <ACTOR_ID>
-
remove-from-whitelist
Remove an Actor ID from the whitelist in the MarketDealWrapper contract.wrappedeal write-contract remove-from-whitelist \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ <ACTOR_ID>
-
add-funds
Add native funds to the MarketDealWrapper contract.wrappedeal write-contract add-funds \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<AMOUNT>"
-
withdraw-funds
Withdraw native funds from the MarketDealWrapper contract.wrappedeal write-contract withdraw-funds \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<AMOUNT>"
-
approve-erc20
Approve the MarketDealWrapper contract to spend ERC20 tokens.wrappedeal write-contract approve-erc20 \ --contract-address "<TOKEN_CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<SPENDER_ADDRESS>" "<AMOUNT>"
-
add-funds-erc20
Add ERC20 tokens to the MarketDealWrapper contract.wrappedeal write-contract add-funds-erc20 \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<TOKEN_ADDRESS>" "<AMOUNT>"
-
withdraw-funds-erc20
Withdraw ERC20 tokens from the MarketDealWrapper contract.wrappedeal write-contract withdraw-funds-erc20 \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<TOKEN_ADDRESS>" "<AMOUNT>"
-
withdraw-sp-funds-by-token
Withdraw total SP funds by ERC20 token from the MarketDealWrapper contract.wrappedeal write-contract withdraw-sp-funds-by-token \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<TOKEN_ADDRESS>"
-
withdraw-sp-funds-for-deal
Withdraw SP funds for a specific deal from the MarketDealWrapper contract.wrappedeal write-contract withdraw-sp-funds-for-deal \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<DEAL_ID>"
-
withdraw-sp-funds-for-terminated-deal
Withdraw SP funds for a terminated deal from the MarketDealWrapper contract.wrappedeal write-contract withdraw-sp-funds-for-terminated-deal \ --contract-address "<ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<DEAL_ID>"
Use read-contract
to read data from the MarketDealWrapper contract.
wrappedeal read-contract [subcommand] [flags] [parameters]
-
get-sp-id
Get Storage Provider address by Actor ID.wrappedeal read-contract get-sp-id \ --contract-address "<ADDRESS>" \ <actor-id>
-
get-deals-from-miner-id
Retrieve deal IDs associated with a given miner ID.wrappedeal read-contract get-deals-from-miner-id \ --contract-address "<ADDRESS>" \ <miner-id>
-
is-whitelisted
Check if an Actor ID is whitelisted.wrappedeal read-contract is-whitelisted \ --contract-address "<ADDRESS>" \ <ACTOR_ID>
-
get-sp-funds-for-deal
Retrieve the currently claimable SP funds for a specific deal.wrappedeal read-contract get-sp-funds-for-deal \ --contract-address "<ADDRESS>" \ <deal-id>
-
get-token-funds-for-sp
Retrieve the currently claimable SP funds for a specific ERC20 token and actor ID.wrappedeal read-contract get-token-funds-for-sp \ --contract-address "<ADDRESS>" \ <token> <actor-id>
Follow the steps below to create and manage a Filecoin deal using Wrapped Deal. Each step includes a description of the action being performed along with the corresponding CLI command. Ensure that all flags are specified before the parameters.
-
Deploy the
MarketDealWrapper
ContractBefore initiating any deals, ensure that the
MarketDealWrapper
smart contract is deployed to your desired network (e.g., Anvil, testnet, or mainnet). This contract will handle the automated payments to Storage Providers (SPs). [Deployed Contract]forge create --rpc-url <YOUR_RPC_URL> --private-key <YOUR_PRIVATE_KEY> src/MarketDealWrapper.sol:MarketDealWrapper
-
Add a Storage Provider (SP)
Register a Storage Provider with the
MarketDealWrapper
contract. This step associates the SP's actor ID, Ethereum address, ERC20 token, and pricing information with the contract, allowing clients to make deals with this SP. [Sp add trans]wrappedeal write-contract add-sp \ --contract-address "<CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ --actor-id <ACTOR_ID> \ --eth-addr "<ETH_ADDRESS>" \ --token "<TOKEN_ADDRESS>" \ --price-per-tb-per-month <PRICE>
-
Get Actor ID of your Filecoin address
To retrieve the actor ID from your Filecoin address, you can run:
wrappedeal fil get-actor-id \ --filecoin-addr "<FILECOIN_ADDRESS>" \
-
Add the Actor ID to Whitelist
Whitelist the actor ID(remove
t0
orf0
prefix) in the MarketDealWrapper contract:wrappedeal write-contract add-to-whitelist \ --contract-address "<CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ <ACTOR_ID>
-
Approve ERC20 Tokens for the Contract
Approve the
MarketDealWrapper
contract to spend a specified amount of your ERC20 tokens. This is necessary to facilitate the transfer of funds from your wallet to the contract for deal payments. You can use USDFC stablecoin (Get address from here) for testing.wrappedeal write-contract approve-erc20 \ --contract-address "<TOKEN_CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<CONTRACT_ADDRESS>" "<AMOUNT>"
-
Add ERC20 Funds to the Contract
Transfer approved ERC20 tokens to the
MarketDealWrapper
contract. These funds will be used to automatically pay the Storage Provider for the deals made. [USDFC add trans]wrappedeal write-contract add-funds-erc20 \ --contract-address "<CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<TOKEN_ADDRESS>" "<AMOUNT>"
-
Make a Local Deal with the SP
Create a local deal with the registered Storage Provider. This command uploads the specified file or folder, associates it with the SP, and records the deal in the contract. The
verified
tag is set totrue
by default. You can get DataCap in Calibnet for your contract from here. [on-chain deal]wrappedeal fil local-deal \ --path "<FILE_OR_FOLDER_PATH>" \ --provider "<SP_ADDRESS>" \ --contract "<CONTRACT_ADDRESS>"
Client Flow Complete
-
Storage Provider Withdraws Funds for a Deal
The registered Storage Provider can withdraw funds for a specific deal at any time. Funds are vested and become available as per the epoch schedule defined in the contract. [Sp's address claims USDFC]
wrappedeal write-contract withdraw-sp-funds-for-deal \ --contract-address "<CONTRACT_ADDRESS>" \ --private-key "<PRIVATE_KEY>" \ --abi-path "<ABI_PATH>" \ --rpc-url "<RPC_URL>" \ "<DEAL_ID>"
Note:
- Funds are vested according to the epoch schedule, ensuring timely and automated payments to the Storage Provider.
- The SP can withdraw funds for a terminated deal using the
withdraw-sp-funds-for-terminated-deal
command. - Client has admin rights to add or remove SPs, whitelist addresses, and manage contract funds.
-
RPC URL and Private Key
- Ensure that the RPC URL and private key are set and sourced from env to avoid passing it everytime.
- The private key should be kept secure and not shared with others.
-
ABI Path
- The ABI path should point to the MarketDealWrapper contract ABI file.
- Ensure that the ABI file has abi in following format
{ "abi": <ABI> }
-
Wallet Type for
get-eth-addr
- The default wallet should be
secp256k1
as we can derive eth-address for that only,bls
is not supported.
- The default wallet should be
-
Build Issues
- If you encounter build issues, ensure that the go.mod file is correctly set up with boost path, etc as mentioned in the prerequisites.
- Verify that the correct version of Go is installed.
-
Actor ID initialization
- Ensure that the Actor ID is initialized correctly for your addresses you are using. You may need to fund the smart contract or EOA with small amounts of FIL to initialize the Actor.
- Foundry Docs: https://book.getfoundry.sh/
- Boost Docs: https://boost.filecoin.io/docs
- Go Modules: https://go.dev/doc/modules
- Faucet: https://faucet.calibnet.chainsafe-fil.io/
Enjoy using Wrapped Deal to streamline and automate your Filecoin deal payments!