SDK
A typed TypeScript client for the launchpad, the charts, the portal and the agents.
Install
npm install @devoxpad/sdk
There is no API key and no auth header. Everything this client reads is public, which is why a browser can call it directly. It points at the public deployment by default, so the two lines below are a working program.
The repository ships a smoke test that calls every method against the live deployment and exits non-zero if anything is broken. Run `npm run smoke` in `sdk/` before you build on top of it.
import { Devoxpad } from "@devoxpad/sdk";
const devox = new Devoxpad();
const tokens = await devox.tokens.list({ sort: "progress", limit: 5 });
const chart = await devox.tokens.candles(tokens[0].address, "5m");
console.log(tokens[0].symbol, chart.spotCoti, "COTI");Everything the SDK exposes is a public read. Nothing it can call moves funds, and no key is needed. Signing is left to your own wallet library, because signing belongs where the keys are.
The client
const devox = new Devoxpad({
baseUrl: "https://devoxpad-app.vercel.app", // this is the default, so it can be omitted
timeoutMs: 20_000,
fetch: myInstrumentedFetch, // your own retry or caching
headers: { "x-app": "my-bot" },
});- baseUrl
- Any DEVOXPAD deployment. Point it at your own instance.
- fetch
- Swap in your own implementation for retries, caching or logging.
- timeoutMs
- Requests abort past this. Default 20000.
- headers
- Merged into every request.
Failures throw a DevoxpadError carrying the HTTP status and the path, so a bad address and a network outage are distinguishable without parsing message strings.
devox.tokens
| Method | Returns |
|---|---|
| list(opts) | TokenSummary[], sortable by new, progress or graduated |
| get(address) | TokenDetail: curve state, pair state, merged trade history |
| candles(address, tf) | OHLCV plus market cap and issued supply |
| trades(address, limit) | Recorded fills |
| comments(address, limit) | The token thread. Private entries carry no body. |
const { curve } = await devox.tokens.get(address);
if (curve && !curve.graduated) {
console.log(curve.progressPct.toFixed(1) + "% of the way to graduation");
console.log(curve.reserveCoti + " of " + curve.targetCoti + " COTI raised");
}TokenDetail exposes isPrivate. When it is true, treat any aggregate supply as unavailable rather than as zero. Use issuedSupply from candles() if you need something to value the token against.
devox.portal
const { pairs } = await devox.portal.pairs();
for (const p of pairs) {
console.log(p.twinSymbol, "backed by", p.locked, p.symbol);
}
const twin = await devox.portal.twinOf(wcotiAddress);Escrow figures are public by design, so a client can verify each twin is fully backed without any special access.
devox.agents
chat() returns an async generator. Every step an agent takes arrives as it happens: the tools it calls, the text it streams, and any proposal it produces for a wallet to sign.
for await (const ev of devox.agents.chat("shade", "what is worth buying")) {
switch (ev.type) {
case "tool_start":
console.log("...", ev.name);
break;
case "text":
process.stdout.write(ev.text);
break;
case "action":
console.log("proposal:", ev.action);
break;
}
}An action event describes a transaction. Nothing happens until your wallet signs it. The SDK will never sign anything for you.
Config and health
const chain = await devox.chain();
if (!chain.deployed.factory) {
throw new Error("The launchpad is not deployed on this network yet");
}
const status = await devox.status();
console.log(status.head, "head,", status.lag, "blocks behind");chain() returns a compact digest of what is actually live, which is the honest way to decide whether an action is possible before offering it to a user.