TypeScript SDK for the Second Layer API.
bun add @secondlayer/sdkimport { SecondLayer } from "@secondlayer/sdk";
const sl = new SecondLayer({
apiKey: "sk-sl_...", // or session token
baseUrl: "https://api.secondlayer.tools", // default
});Deploy and query subgraphs (custom indexers).
// List
const { data } = await sl.subgraphs.list();
// Get
const subgraph = await sl.subgraphs.get("my-subgraph");
// Query table
const rows = await sl.subgraphs.queryTable("my-subgraph", "transfers", {
sort: "block_height",
order: "desc",
limit: 50,
});
// Deploy
const result = await sl.subgraphs.deploy({ name, sources, schema, handlerCode });Per-row HTTP webhooks from subgraph tables.
// List / get
const { data } = await sl.subscriptions.list();
const sub = await sl.subscriptions.get(id);
// Create — sink a subgraph table to a signed webhook endpoint.
// `signingSecret` is returned ONCE; store it in the receiver's env.
const { subscription, signingSecret } = await sl.subscriptions.create({
name: "whale-alerts",
subgraphName: "transfers",
tableName: "events",
url: "https://example.com/hooks/transfers",
format: "standard-webhooks", // or inngest | trigger | cloudflare | cloudevents | raw
});
// Lifecycle
await sl.subscriptions.update(id, { filter: { amount: { gte: "1000000" } } });
await sl.subscriptions.pause(id);
await sl.subscriptions.resume(id);
await sl.subscriptions.rotateSecret(id); // returns new signing secret once
const { data: deliveries } = await sl.subscriptions.recentDeliveries(id);
// Replay historical block range
await sl.subscriptions.replay(id, { fromBlock: 180000, toBlock: 181000 });
// Dead-letter inspection + requeue
const { data: dead } = await sl.subscriptions.dead(id);
await sl.subscriptions.requeueDead(id, outboxId);import { ApiError } from "@secondlayer/sdk";
try {
await sl.subgraphs.get("nonexistent");
} catch (err) {
if (err instanceof ApiError) {
console.log(err.status); // 404
console.log(err.message); // "Contract not found"
}
}