Type-safe contract interfaces, functions, and React hooks for Clarity smart contracts.
bun add -g @secondlayer/cliGenerate from local files or deployed contracts—no config required:
# Local .clar files
secondlayer generate ./contracts/token.clar -o ./src/generated.ts
# Deployed contracts (network inferred from address)
secondlayer generate SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.alex-vault -o ./src/generated.ts
# Glob patterns
secondlayer generate "./contracts/*.clar" -o ./src/generated.tssecondlayer init # creates secondlayer.config.ts
secondlayer generate// secondlayer.config.ts
import { defineConfig } from '@secondlayer/cli'
import { clarinet, actions, react } from '@secondlayer/cli/plugins'
export default defineConfig({
out: 'src/generated.ts',
plugins: [
clarinet(), // parse local Clarinet project
actions(), // add read/write helpers
react(), // generate React hooks
],
})import { token } from './generated/contracts'
import { makeContractCall, fetchCallReadOnlyFunction } from '@stacks/transactions'
// works with @stacks/transactions directly
await makeContractCall({
...token.transfer({ amount: 100n, recipient: "SP..." }),
network: 'mainnet',
})
await fetchCallReadOnlyFunction({
...token.getBalance({ account: "SP..." }),
network: 'mainnet',
})Requires actions() plugin:
// read-only
const balance = await token.read.getBalance({ account: "SP..." })
// write (uses STX_SENDER_KEY env var)
await token.write.transfer({ amount: 100n, recipient: "SP..." })
// or pass senderKey explicitly
await token.write.transfer({ amount: 100n, recipient: "SP..." }, "<sender-key>")
// with additional options
await token.write.transfer({ amount: 100n, recipient: "SP..." }, "<sender-key>", { network: 'testnet' })Access maps, variables, constants directly:
// maps
const balance = await token.maps.balances.get("SP...")
// variables
const supply = await token.vars.totalSupply.get()
// constants
const max = await token.constants.maxSupply.get()
// network override
const devBalance = await token.maps.balances.get("SP...", { network: 'devnet' })Requires react() plugin:
import { useTokenTransfer, useTokenBalances, useTokenTotalSupply } from './generated/hooks'
function App() {
const { transfer, isRequestPending } = useTokenTransfer()
const { data: balance } = useTokenBalances("SP...")
const { data: supply } = useTokenTotalSupply()
return (
<button onClick={() => transfer({ amount: 100n, recipient: "SP..." })} disabled={isRequestPending}>
Transfer
</button>
)
}Requires testing() plugin:
import { getContracts } from './helpers'
const simnet = await initSimnet()
const { token } = getContracts(simnet)
// call functions
const result = token.transfer({ amount: 100n, recipient: "ST..." }, "wallet_1")
expect(result.result).toBeOk(Cl.bool(true))
// read state
const supply = token.vars.totalSupply()
const balance = token.maps.balances("ST...")| Plugin | Description |
|---|---|
clarinet() |
Parse local Clarinet project |
actions() |
Add read/write helpers |
react() |
Generate React hooks |
testing() |
Generate Clarinet SDK test helpers |
Address prefix determines network:
SP/SM→ mainnetST/SN→ testnet
Second Layer also provides a hosted indexing platform with real-time streams, subgraphs, and contract discovery.
bun add -g @secondlayer/cli
sl auth login # authenticate via magic link
sl streams list # manage event streams
sl subgraphs list # manage subgraphsAll commands support --json for machine-readable output.
bun add @secondlayer/sdkimport { SecondLayer } from "@secondlayer/sdk";
const sl = new SecondLayer({ apiKey: "sk-sl_..." });
// List streams
const { streams, total } = await sl.streams.list({ status: "active" });
// Create a stream
const { stream, signingSecret } = await sl.streams.create({
name: "my-stream",
endpointUrl: "https://example.com/receive",
filters: { type: "contract_call", contract_id: "SP...token" },
});
// List subgraphs
const { data } = await sl.subgraphs.list();Base URL: https://api.secondlayer.tools
# List streams
curl -H "Authorization: Bearer $TOKEN" \
"https://api.secondlayer.tools/api/streams"
# List subgraphs
curl -H "Authorization: Bearer $TOKEN" \
"https://api.secondlayer.tools/api/subgraphs"See packages/api/README.md and packages/sdk/README.md for full docs.
Connect AI agents to Second Layer via MCP:
bun add @secondlayer/mcpSee packages/mcp/README.md for IDE and HTTP setup.
MIT