ocft
v1.2.1
Published
OpenClaw File Transfer Protocol - P2P file transfer between bots
Maintainers
Readme
OCFT - OpenClaw File Transfer Protocol
P2P file transfer between AI agents via message channels.
Features
- 🔗 Message-based: Transfer files through existing chat channels
- 📦 Chunked transfer: Split large files into small pieces
- ✅ Integrity verification: SHA-256 hash for chunks and files
- 🤝 Request/Accept: Explicit acceptance or auto-accept policy
- 🔒 Security: Trusted peer whitelist with secrets
- ⏰ Secret TTL: Set expiry time for trust relationships
- 🔄 Resume: Resume interrupted transfers from last chunk
- 🌐 IPFS Fallback: Auto-upload large files to IPFS
Installation
npm install -g ocftQuick Start
# Initialize your node (generates unique ID and secret)
ocft init
# View your status
ocft status
# Export your connection info to share with peers
ocft export
# Add a trusted peer (with optional TTL)
ocft add-peer <nodeId> <secret> --name "Friend" --ttl 24
# Or import from URI
ocft import ocft://eyJub2RlSWQ... --ttl 48CLI Commands
| Command | Description |
|---------|-------------|
| ocft init | Initialize node with unique ID and secret |
| ocft status | Show node status and configuration |
| ocft show-secret | Display full secret (careful!) |
| ocft export | Export connection info as URI |
| ocft import <uri> | Import peer from ocft:// URI |
| ocft add-peer <id> <secret> | Add a trusted peer |
| ocft remove-peer <id> | Remove a trusted peer |
| ocft list-peers | List all trusted peers |
| ocft set-download <dir> | Set download directory |
| ocft set-max-size <size> | Set max file size (e.g., 500MB, 2GB) |
| ocft set-ttl <hours> | Set default secret TTL for offers |
| ocft extend-peer <id> <hours> | Extend a peer's trust expiry |
| ocft verify <secret> | Verify if a secret matches yours |
IPFS Fallback
For large files or when the receiver doesn't support OCFT, files can be uploaded to IPFS instead.
Supported Providers
| Provider | Description |
|----------|-------------|
| pinata | Pinata Cloud (default) - requires JWT token |
| filebase | Filebase (S3-compatible) - requires access key + secret |
| kubo | Local IPFS node - no auth required |
IPFS Commands
# Enable IPFS fallback
ocft ipfs-enable
# Set provider
ocft set-ipfs-provider pinata # or: filebase, kubo
# Configure credentials
ocft set-ipfs-key <jwt-token> # Pinata
ocft set-ipfs-key <access-key> --secret <secret> # Filebase
ocft set-kubo-url http://localhost:5001 # Kubo (local node)
# Set size threshold (files larger than this use IPFS)
ocft set-ipfs-threshold 50MB
# Set custom public gateway
ocft set-ipfs-gateway https://ipfs.io/ipfsHow It Works
- If file size > threshold (default 50MB), upload to IPFS
- If receiver doesn't support OCFT, send IPFS link instead
- Receiver downloads from public IPFS gateway
[Sender] [IPFS] [Receiver]
│ │ │
│── Upload (file > 50MB) ───────────>│ │
│<────────────────── CID ────────────│ │
│── Send IPFS link ──────────────────────────────────────────────>│
│ │<── Download from gateway ──│Protocol Flow
[Sender] [Receiver]
│ │
│── OFFER ─────────────────>│ (file metadata + secret + TTL)
│<───────────── ACCEPT ─────│ (auto-accept if secret valid & not expired)
│── CHUNK[0] ──────────────>│
│<───────────── ACK[0] ─────│
│── CHUNK[1] ──────────────>│
│<───────────── ACK[1] ─────│
│... │
│── COMPLETE ──────────────>│
│<───────────── ACK ────────│Resume Interrupted Transfers
If a transfer is interrupted, it can be resumed from the last acknowledged chunk:
// Resume a failed transfer
await bot.resumeTransfer(transferId);
// Get list of resumable transfers
const resumable = bot.getResumableTransfers();The receiver sends resumeFrom in the ACCEPT message, and the sender starts from that chunk index.
Secret TTL (Time-To-Live)
Set expiry time for trust relationships:
# Add peer with 24-hour trust
ocft add-peer abc123 secret123 --ttl 24
# Set default TTL for all outgoing offers
ocft set-ttl 48
# Extend an existing peer's trust
ocft extend-peer abc123 24Expired secrets are automatically rejected.
Secret-Based Auto-Accept
When the sender knows the receiver's secret, files are automatically accepted without manual approval:
- Bot A shares their secret with Bot B
- Bot B adds Bot A as trusted peer with the secret
- When Bot B sends a file to Bot A, it includes A's secret
- Bot A verifies the secret (and TTL) and auto-accepts
This enables trusted agent networks to share files seamlessly.
Programmatic Usage
import { TransferManager } from 'ocft';
const bot = new TransferManager({
botId: 'my-bot',
secret: 'my-secret',
secretTTL: 24 * 60 * 60 * 1000, // 24 hours in ms
downloadDir: './downloads',
trustedPeers: [
{ id: 'friend-bot', secret: 'friends-secret', expiresAt: Date.now() + 86400000 }
]
}, async (to, message) => {
await sendMessage(to, message);
});
// Event handlers
bot.on('offer-received', (transfer) => console.log(`Incoming: ${transfer.filename}`));
bot.on('transfer-completed', (transfer) => console.log(`Saved: ${transfer.localPath}`));
// Send a file
await bot.sendFile('friend-bot', '/path/to/file.txt');
// Resume interrupted transfer
await bot.resumeTransfer(transferId);
// Get resumable transfers
const resumable = bot.getResumableTransfers();Message Format
OCFT messages use a 🔗OCFT: prefix with Base64-encoded JSON:
🔗OCFT:eyJ2ZXJzaW9uIjoiMS4wIiwidHlwZSI6Im9mZmVyIi4uLn0=This allows file transfers over any text-based channel (Telegram, Discord, Slack, etc).
Configuration
Config is stored at ~/.ocft/config.json:
{
"nodeId": "ocft_abc123_xyz789",
"secret": "your-secret-key",
"secretTTL": 24,
"trustedPeers": [
{ "id": "peer-id", "secret": "peer-secret", "expiresAt": "2026-02-03T00:00:00Z" }
],
"downloadDir": "~/Downloads/ocft",
"maxFileSize": 1073741824,
"ipfsEnabled": true,
"ipfsProvider": "pinata",
"ipfsThreshold": 52428800,
"ipfsApiKey": "your-pinata-jwt"
}Limitations
- Chunk size: 48KB (safe for Base64 in messages)
- Default max file size: 100MB (configurable)
- IPFS threshold: 50MB (configurable)
- Designed for text-based channels
License
MIT
