7.5kā
by romovow
poseidon-otc ā OpenClaw Skill
poseidon-otc is an OpenClaw Skills integration for coding workflows. Execute trustless P2P token swaps on Solana via the Poseidon OTC protocol. Create trade rooms, negotiate offers, lock tokens with time-based escrow, and execute atomic on-chain swaps. Supports agent-to-agent trading with real-time WebSocket updates.
Skill Snapshot
| name | poseidon-otc |
| description | Execute trustless P2P token swaps on Solana via the Poseidon OTC protocol. Create trade rooms, negotiate offers, lock tokens with time-based escrow, and execute atomic on-chain swaps. Supports agent-to-agent trading with real-time WebSocket updates. OpenClaw Skills integration. |
| owner | romovow |
| repository | romovow/poseidon-otc |
| language | Markdown |
| license | MIT |
| topics | |
| security | L1 |
| install | openclaw add @romovow/poseidon-otc |
| last updated | Feb 7, 2026 |
Maintainer

name: poseidon-otc description: Execute trustless P2P token swaps on Solana via the Poseidon OTC protocol. Create trade rooms, negotiate offers, lock tokens with time-based escrow, and execute atomic on-chain swaps. Supports agent-to-agent trading with real-time WebSocket updates. metadata: { "openclaw": { "emoji": "š±", "requires": { "env": ["POSEIDON_BURNER_KEY"] }, "primaryEnv": "POSEIDON_BURNER_KEY", "homepage": "https://poseidon.cash" } }
Poseidon OTC Skill
TL;DR for Agents: This skill lets you trade tokens with humans or other agents on Solana. You create a room, both parties deposit tokens to escrow, confirm, and execute an atomic swap. No trust required - it's all on-chain.
When to Use This Skill
- Trading tokens P2P - Swap any SPL token directly with another party
- Agent-to-agent commerce - Two AI agents can negotiate and execute trades autonomously
- Large OTC deals - Avoid slippage from DEX trades by going direct
- Protected trades - Use lockups to prevent counterparty from dumping immediately
- Multi-token swaps - Trade up to 4 tokens per side in one atomic transaction
Quick Start for Agents
1. Initialize (requires wallet)
import { PoseidonOTC } from 'poseidon-otc-skill';
const client = new PoseidonOTC({
burnerKey: process.env.POSEIDON_BURNER_KEY // base58 private key
});
2. Create a Trade Room
const { roomId, link } = await client.createRoom();
// Share `link` with counterparty or another agent
3. Wait for Counterparty & Set Offer
// Check room status
const room = await client.getRoom(roomId);
// Set what you're offering (100 USDC example)
await client.updateOffer(roomId, [{
mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC mint
amount: 100000000, // 100 USDC (6 decimals)
decimals: 6
}]);
4. Confirm & Execute
// First confirmation = "I agree to these terms"
await client.confirmTrade(roomId, 'first');
// After deposits, second confirmation
await client.confirmTrade(roomId, 'second');
// Execute the atomic swap
const { txSignature } = await client.executeSwap(roomId);
Complete Trade Flow
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā TRADE LIFECYCLE ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā 1. CREATE ROOM ā
ā āā> Party A calls createRoom() ā
ā Returns: roomId, shareable link ā
ā ā
ā 2. JOIN ROOM ā
ā āā> Party B calls joinRoom(roomId) ā
ā Room now has both participants ā
ā ā
ā 3. SET OFFERS ā
ā āā> Both parties call updateOffer(roomId, tokens) ā
ā Each specifies what they're putting up ā
ā ā
ā 4. FIRST CONFIRM (agree on terms) ā
ā āā> Both call confirmTrade(roomId, 'first') ā
ā "I agree to swap my X for your Y" ā
ā ā
ā 5. DEPOSIT TO ESCROW ā
ā āā> Tokens move to on-chain escrow ā
ā (Handled by frontend or depositToEscrow) ā
ā ā
ā 6. SECOND CONFIRM (verify deposits) ā
ā āā> Both call confirmTrade(roomId, 'second') ā
ā "I see the deposits, ready to swap" ā
ā ā
ā 7. EXECUTE SWAP ā
ā āā> Either party calls executeSwap(roomId) ā
ā Atomic on-chain swap via relayer ā
ā Returns: txSignature ā
ā ā
ā [OPTIONAL] LOCKUP FLOW ā
ā āā> Before step 4, Party A can proposeLockup(roomId, secs) ā
ā āā> Party B must acceptLockup(roomId) to continue ā
ā āā> After execute, locked tokens claimed via claimLockedTokens ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
API Reference
Room Management
| Method | Parameters | Returns | Description |
|---|---|---|---|
createRoom(options?) | { inviteCode?: string } | { roomId, link } | Create new room |
getRoom(roomId) | roomId: string | TradeRoom | Get full room state |
getUserRooms(wallet?) | wallet?: string | TradeRoom[] | List your rooms |
joinRoom(roomId, inviteCode?) | roomId, inviteCode? | { success } | Join as Party B |
cancelRoom(roomId) | roomId: string | { success } | Cancel & refund |
getRoomLink(roomId) | roomId: string | string | Get share URL |
Trading
| Method | Parameters | Returns | Description |
|---|---|---|---|
updateOffer(roomId, tokens) | roomId, [{mint, amount, decimals}] | { success } | Set your offer |
withdrawFromOffer(roomId, tokens) | roomId, tokens[] | { success } | Pull back tokens |
confirmTrade(roomId, stage) | roomId, 'first'ā'second' | { success } | Confirm stage |
executeSwap(roomId) | roomId: string | { txSignature } | Execute swap |
declineOffer(roomId) | roomId: string | { success } | Reject terms |
Lockups (Anti-Dump)
| Method | Parameters | Returns | Description |
|---|---|---|---|
proposeLockup(roomId, seconds) | roomId, seconds | { success } | Propose lock |
acceptLockup(roomId) | roomId: string | { success } | Accept lock |
getLockupStatus(roomId) | roomId: string | { canClaim, timeRemaining } | Check timer |
claimLockedTokens(roomId) | roomId: string | { txSignature } | Claim after expiry |
Utility
| Method | Parameters | Returns | Description |
|---|---|---|---|
getBalance() | none | { sol: number } | Check SOL balance |
isAutonomous() | none | boolean | Has signing wallet? |
getWebSocketUrl() | none | string | Get WS endpoint |
WebSocket Real-Time Updates
Don't poll. Subscribe.
Instead of repeatedly calling getRoom(), connect to WebSocket for instant updates:
Endpoint: wss://poseidon.cash/ws/trade-room
Subscribe to Room Events
const { unsubscribe } = await client.subscribeToRoom(roomId, (event) => {
switch (event.type) {
case 'join':
console.log('Counterparty joined!');
break;
case 'offer':
console.log('Offer updated:', event.data.tokens);
break;
case 'confirm':
console.log('Confirmation received');
break;
case 'execute':
console.log('Swap complete! TX:', event.data.txSignature);
break;
case 'cancel':
console.log('Trade cancelled');
break;
}
});
Event Types
| Event | When It Fires |
|---|---|
full-state | Immediately on subscribe - complete room state |
join | Counterparty joined the room |
offer | Someone updated their offer |
confirm | Someone confirmed (first or second) |
lockup | Lockup proposed or accepted |
execute | Swap executed successfully |
cancel | Room was cancelled |
terminated | Room expired or terminated |
error | Something went wrong |
WebSocket Actions (Faster than HTTP)
await client.sendOfferViaWs(roomId, tokens); // Update offer
await client.sendConfirmViaWs(roomId, 'first'); // Confirm
await client.sendLockupProposalViaWs(roomId, 3600); // Propose 1hr lock
await client.sendAcceptLockupViaWs(roomId); // Accept lock
await client.sendExecuteViaWs(roomId); // Execute swap
Agent-to-Agent Trading Example
Scenario: Agent A wants to sell 1000 USDC for 5 SOL to Agent B
Agent A (Seller):
// 1. Create room
const { roomId } = await client.createRoom();
// 2. Set offer (1000 USDC)
await client.updateOffer(roomId, [{
mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: 1000000000, // 1000 USDC
decimals: 6
}]);
// 3. Share roomId with Agent B via your inter-agent protocol
// 4. Subscribe to updates
await client.subscribeToRoom(roomId, async (event) => {
if (event.type === 'offer') {
// Check if Agent B's offer is acceptable (5 SOL)
const room = await client.getRoom(roomId);
if (room.partyBTokenSlots?.[0]?.amount >= 5 * 1e9) {
await client.confirmTrade(roomId, 'first');
}
}
if (event.type === 'confirm' && room.partyBFirstConfirm) {
await client.confirmTrade(roomId, 'second');
}
});
Agent B (Buyer):
// 1. Join the room
await client.joinRoom(roomId);
// 2. Set offer (5 SOL)
await client.updateOffer(roomId, [{
mint: 'So11111111111111111111111111111111111111112', // wSOL
amount: 5000000000, // 5 SOL
decimals: 9
}]);
// 3. Subscribe and react
await client.subscribeToRoom(roomId, async (event) => {
if (event.type === 'confirm') {
const room = await client.getRoom(roomId);
if (room.partyAFirstConfirm && !room.partyBFirstConfirm) {
await client.confirmTrade(roomId, 'first');
}
if (room.partyASecondConfirm && room.partyBSecondConfirm) {
// Both confirmed, execute!
await client.executeSwap(roomId);
}
}
});
Common Token Mints
| Token | Mint Address | Decimals |
|---|---|---|
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | 6 |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB | 6 |
| wSOL | So11111111111111111111111111111111111111112 | 9 |
| BONK | DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 | 5 |
Environment Variables
POSEIDON_BURNER_KEY=<base58-private-key> # Required for autonomous mode
POSEIDON_API_URL=https://poseidon.cash # API endpoint (default: mainnet)
POSEIDON_RPC_URL=https://api.mainnet-beta.solana.com # Solana RPC
Security Notes
- Escrow is on-chain - Funds are held by the Solana program, not the API
- Atomic swaps - Either both sides complete or neither does
- Signatures expire - Auth signatures valid for 24 hours
- Lockups are enforced on-chain - Can't bypass the timer
- Hot wallet warning - Only fund your burner wallet with amounts you're comfortable risking
Program ID
Mainnet: AfiRReYhvykHhKXhwjhcsXFejHdxqYLk2QLWnjvvLKUN
Links
- Website: https://poseidon.cash
- Docs: https://docs.poseidon.cash
Poseidon OTC
Trustless P2P token swaps on Solana.
Overview
Poseidon OTC enables direct peer-to-peer token trading without intermediaries. Both parties deposit into escrow, confirm the terms, and the swap executes atomically on-chain.
Features:
- Multi-token swaps (up to 4 tokens per side)
- Optional time-locks to protect against dumps
- Private rooms with invite codes
- No counterparty risk - escrow holds funds until both confirm
Installation
npm install poseidon-otc-skill
Or clone directly:
git clone https://github.com/poseidon-cash/poseidon-otc-skill
cd poseidon-otc-skill
npm install && npm run build
Usage
Link Mode (Default)
Returns trade room links for manual wallet signing:
import { PoseidonOTC } from 'poseidon-otc-skill';
const client = new PoseidonOTC();
const result = await client.createRoom();
// { success: true, roomId: '...', link: 'https://poseidon.cash/trade-room/...' }
Autonomous Mode
For fully automated execution with a dedicated wallet:
const client = new PoseidonOTC({
burnerKey: 'your-base58-private-key'
});
await client.createRoom({ inviteCode: 'secret' });
await client.joinRoom(roomId);
await client.updateOffer(roomId, [
{ mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', amount: 100000000, decimals: 6 }
]);
await client.confirmTrade(roomId, 'first');
API Reference
| Method | Description |
|---|---|
createRoom(options?) | Create a new trade room |
getRoom(roomId) | Get room status and details |
getUserRooms(wallet?) | List all rooms for a wallet |
joinRoom(roomId, inviteCode?) | Join as counterparty |
updateOffer(roomId, tokens) | Set your token offer |
withdrawFromOffer(roomId, tokens) | Withdraw tokens from escrow |
confirmTrade(roomId, stage) | Confirm trade (first/second) |
executeSwap(roomId) | Execute the atomic swap |
proposeLockup(roomId, seconds) | Propose lockup on counterparty's tokens |
acceptLockup(roomId) | Accept the proposed lockup |
getLockupStatus(roomId) | Check lockup timer status |
claimLockedTokens(roomId) | Claim tokens after lockup expires |
cancelRoom(roomId) | Cancel and refund all deposits |
declineOffer(roomId) | Decline current offer |
getRoomLink(roomId) | Get shareable URL |
getBalance() | Check wallet SOL balance |
isAutonomous() | Check if running with wallet |
Trade Flow
- Create Room - Party A creates a room, optionally with invite code
- Join Room - Party B joins using the room link
- Set Offers - Both parties specify their token amounts
- First Confirm - Both confirm the trade terms
- Deposit - Both deposit tokens to escrow (via frontend)
- Second Confirm - Both confirm deposits are correct
- Execute - Relayer executes atomic swap on-chain
Environment Variables
POSEIDON_API_URL=https://poseidon.cash # API endpoint
POSEIDON_RPC_URL=https://api.mainnet-beta.solana.com # Solana RPC
POSEIDON_BURNER_KEY=<base58-private-key> # For autonomous mode
OpenClaw Integration
Add to your skills.json:
{
"skills": [{
"name": "poseidon-otc",
"path": "./skills/poseidon-otc-skill"
}]
}
Example prompts:
- "Create an OTC trade room"
- "Check status of room ABC123"
- "Join the trade at poseidon.cash/trade-room/XYZ"
- "Cancel my trade room"
Security
- All funds held in on-chain escrow until swap
- Identity authentication via signed messages
- Time-based signature expiry (24 hours)
- Optional lockups to prevent immediate dumps
Warning: Autonomous mode requires funding a hot wallet. Only deposit amounts you're comfortable risking.
Program
Mainnet: AfiRReYhvykHhKXhwjhcsXFejHdxqYLk2QLWnjvvLKUN
Links
- Website: https://poseidon.cash
- Docs: https://docs.poseidon.cash
License
MIT
Permissions & Security
Security level L1: Low-risk skills with minimal permissions. Review inputs and outputs before running in production.
- **Escrow is on-chain** - Funds are held by the Solana program, not the API - **Atomic swaps** - Either both sides complete or neither does - **Signatures expire** - Auth signatures valid for 24 hours - **Lockups are enforced on-chain** - Can't bypass the timer - **Hot wallet warning** - Only fund your burner wallet with amounts you're comfortable risking
Requirements
- OpenClaw CLI installed and configured.
- Language: Markdown
- License: MIT
- Topics:
FAQ
How do I install poseidon-otc?
Run openclaw add @romovow/poseidon-otc in your terminal. This installs poseidon-otc into your OpenClaw Skills catalog.
Does this skill run locally or in the cloud?
OpenClaw Skills execute locally by default. Review the SKILL.md and permissions before running any skill.
Where can I verify the source code?
The source repository is available at https://github.com/openclaw/skills/tree/main/skills/romovow/poseidon-otc. Review commits and README documentation before installing.
