Skip to content

stormixus/ocft

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 ocft

Quick 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 48

CLI 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/ipfs

How It Works

  1. If file size > threshold (default 50MB), upload to IPFS
  2. If receiver doesn't support OCFT, send IPFS link instead
  3. 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 24

Expired secrets are automatically rejected.

Secret-Based Auto-Accept

When the sender knows the receiver's secret, files are automatically accepted without manual approval:

  1. Bot A shares their secret with Bot B
  2. Bot B adds Bot A as trusted peer with the secret
  3. When Bot B sends a file to Bot A, it includes A's secret
  4. 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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published