@toju.network/fil
v1.0.0
Published
Pay for storage with USDFC on IPFS using Storacha's Hot storage network.
Readme
@toju.network/fil
Pay for decentralized storage on IPFS via Storacha with USDFC (Filecoin stablecoin). No credit cards, no subscriptions.
Features:
- Estimate upload costs in USDFC (1:1 with USD)
- Pay for storage with USDFC via ERC-20 transfer
- Single and multi-file (directory) uploads
- Upload history with expiration tracking
- Email warnings before files expire
- Storage renewal — extend duration for existing uploads
- Automatic cleanup of expired files
Looking for SOL payments? See @toju.network/sol.
Install
pnpm add @toju.network/filYou'll also need wagmi for wallet connection and transaction signing.
Quick start
import { useUpload, Environment } from '@toju.network/fil';
import { useAccount, useWriteContract } from 'wagmi';
const UploadComponent = () => {
const [files, setFiles] = useState<File[]>([]);
const [duration, setDuration] = useState(30);
const client = useUpload(Environment.calibration);
const { address } = useAccount();
const { writeContractAsync } = useWriteContract();
const handleUpload = async () => {
const result = await client.createDeposit({
userAddress: address,
file: files,
durationDays: duration,
sendTransaction: async (txData) => {
const hash = await writeContractAsync({
address: txData.contractAddress,
abi: txData.abi,
functionName: 'transfer',
args: [txData.recipient, txData.amount],
});
return hash;
},
});
if (result.success) {
console.log('Uploaded:', result.cid);
console.log('Transaction:', result.transactionHash);
}
};
return <>// your markup</>;
};Environments
import { Environment } from '@toju.network/fil';
const client = useUpload(Environment.calibration); // Filecoin Calibration (testnet)
const client = useUpload(Environment.mainnet); // Filecoin MainnetYou can also pass a custom API endpoint and RPC URL:
const client = useUpload(Environment.mainnet, 'https://your-rpc.com', 'https://api.toju.network');Estimate cost
const estimate = await client.estimateStorageCost(files, 30);
console.log(`Cost: ${estimate.usdfc} USDFC ($${estimate.usd})`);USDFC is pegged 1:1 to USD — no price conversion needed.
Upload files
const result = await client.createDeposit({
userAddress: address,
file: files,
durationDays: 30,
userEmail: '[email protected]', // optional — get warned 7 days before expiry
sendTransaction: async (txData) => {
const hash = await writeContractAsync({
address: txData.contractAddress,
abi: txData.abi,
functionName: 'transfer',
args: [txData.recipient, txData.amount],
});
return hash;
},
});Note: You'll need FIL (or tFIL on testnet) in your wallet for gas fees.
Upload history
const history = await client.getUserUploadHistory(address, 1, 20);
console.log(history.data); // array of uploads
console.log(history.total);Storage renewal
Extend storage before it expires:
// get a quote
const quote = await client.getStorageRenewalCost(cid, 30);
console.log(`Cost: ${quote.costInUsdfc} USDFC`);
console.log(`New expiration: ${quote.newExpirationDate}`);
// renew
const result = await client.renewStorageDuration({
cid,
duration: 30,
userAddress: address,
sendTransaction: async (txData) => {
const hash = await writeContractAsync({
address: txData.contractAddress,
abi: txData.abi,
functionName: 'transfer',
args: [txData.recipient, txData.amount],
});
return hash;
},
});Renewal keeps the same CID — existing links stay valid.
USDFC token contracts
| Network | Contract Address |
|---|---|
| Filecoin Mainnet | 0x80B98d3aa09ffff255c3ba4A241111Ff1262F045 |
| Filecoin Calibration | 0xb3042734b608a1B16e9e86B374A3f3e389B4cDf0 |
Getting test tokens
- Get tFIL (for gas) from the Filecoin Calibration Faucet
- Mint test USDFC at stg.usdfc.net
Links
Contributing
See the Contributing guide.
