@telaro/sendai
v0.1.0
Published
Drop-in Telaro adapter for SendAI Agent Kit. One line to make every agent action automatically bonded + scored.
Maintainers
Readme
@telaro/sendai
Drop-in Telaro adapter for SendAI Agent Kit. One line to make every agent action automatically bonded + scored.
Install
npm install @telaro/sendai @telaro/sdk solana-agent-kitUse
import { SolanaAgentKit } from "solana-agent-kit";
import { withTelaro } from "@telaro/sendai";
import { PublicKey } from "@solana/web3.js";
const agent = new SolanaAgentKit(
privateKey,
"https://api.devnet.solana.com",
openaiKey
);
const bonded = withTelaro(agent, {
bondAmount: 100_000_000n, // 100 USDC bond
scorer: new PublicKey("ScorerPubkeyOfTheIndexer..."),
bondMint: new PublicKey("4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"),
});
// Use `bonded` exactly like `agent`. Every tx-emitting call now auto-records:
const tx = await bonded.trade("USDC", "SOL", 100);
// ↑ this:
// 1. swaps via Jupiter (SendAI's normal behavior)
// 2. records ActionKind.Swap / value=100 USDC / outcome=Success on-chainWhat it does
- Lazy register on first call — first tx through the wrapped agent
triggers
init_agent+bond_agent(single tx). Subsequent calls re-use the existing on-chain Agent. - Post-tx record — every wrapped method has
recordActionchained to it. ActionKind is inferred from the method name (trade→Swap,lend→Lend,addLiquidity→Lp, etc.); falls back toCustom. - Outcome tracking — if the wrapped call throws,
outcome=Failedis recorded; otherwiseSuccess. - Value extraction — best-effort heuristic looks for
amount/valueAtomic/ numeric first arg.
Action kind mapping
| SendAI method | ActionKind |
|---|---|
| trade, swap, buy, sell, jupiterSwap | Swap |
| addLiquidity, removeLiquidity, openPosition, closePosition | Lp |
| lend, borrow, repay | Lend |
| stake, unstake | Stake |
| vote | Vote |
| bridge | Bridge |
| anything else | Custom |
Why this pattern (not a fork)
- Zero touch on SendAI source — opt-in by users, no PR/upstream review burden
- Adapter ages well — SendAI can change internals; we only need their public method names to keep working
- Idempotent —
withTelaro()is safe to call twice; second call returns the same instance
Production checklist
- [x] Use a paid RPC (
HeliusorTriton) on mainnet — devnet public RPC is rate-limited - [x] Set
scorerto your indexer's pubkey, not a random key - [x] Fund the controller wallet with SOL (~0.05 for register + bond rent) and USDC ≥
bondAmount - [x] Pipe
onRecordErrorinto your existing observability so silent record failures surface - [ ] When SendAI updates: confirm method-name → ActionKind mapping is still correct (PR welcome)
License
MIT
