skills/compose/SKILL.md
Use this skill when the user asks about Goldsky Compose — the offchain-to-onchain TypeScript framework for onchain oracles, keepers, circuit breakers, and cross-chain automation. Triggers on: 'goldsky compose', 'compose.yaml', 'compose deploy/init/dev', 'compose task', 'cron task onchain', 'sponsored gas', 'writeContract from TypeScript', 'build a price oracle', 'resolve prediction market', 'onchain event listener', 'HTTP-triggered task', 'smart wallet'. Also use when the user wants to run TypeScript against EVM chains with managed gas, schedule onchain writes via cron, react to onchain events, or deploy a serverless task with secrets and a smart wallet. For debugging a broken app, use /compose-doctor. For manifest/CLI/API lookups, use /compose-reference. Do NOT trigger on Goldsky Turbo, Mirror, Subgraphs, Edge, or Datasets — those belong to their respective skills.
npx skillsauth add goldsky-io/goldsky-agent composeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Goldsky Compose is the offchain-to-onchain framework for high-stakes systems. Write TypeScript tasks that run in verifiable sandboxes — triggered by cron, HTTP, or onchain events — with smart wallets, gas sponsorship, and durable collections. Typical use cases: custom price oracles, keepers, circuit breakers, prediction-market resolvers, cross-chain automation, identity/attestation flows, and notifications.
/compose-doctor./compose-reference.goldsky login, use /auth-setup. For generic secret management, use /secrets.Before running commands, check if the Bash tool is available:
compose dev for hot-reload local dev; compose deploy to ship; compose logs -f to tail.curl https://goldsky.com | sh
goldsky login
goldsky compose init <app-name> # scaffolds a Bitcoin-oracle example
cd <app-name>
goldsky compose dev # hot-reload local server on :4000
goldsky compose deploy # bundle + upload to cloud
goldsky compose status # expect RUNNING
goldsky compose logs -f # stream logs
compose.yaml + task# compose.yaml
name: my-oracle
api_version: stable
secrets:
- ORACLE_ADDRESS
tasks:
- name: hourly_update
path: src/tasks/hourly-update.ts
triggers:
- type: cron
expression: "0 * * * *"
// src/tasks/hourly-update.ts
import type { TaskContext } from "compose";
export async function main({ evm, env, logEvent }: TaskContext) {
const wallet = await evm.wallet({ name: "updater" });
const tx = await wallet.writeContract(
evm.chains.polygonAmoy,
env.ORACLE_ADDRESS,
"update(uint256)",
[BigInt(Date.now())],
{ confirmations: 3, onReorg: { action: { type: "replay" }, depth: 200 } },
);
await logEvent({ code: "updated", message: "ok", data: { hash: tx.hash } });
}
A task is a TypeScript file exporting async function main(context, params?). Each task declares one or more triggers in compose.yaml.
| Type | Fires on | Key config |
| --------------- | ---------------------------- | ------------------------------------------------------------------------- |
| cron | schedule | expression (5-field cron) |
| http | HTTP POST to /tasks/<name> | authentication: auth_token \| none, optional ip_whitelist |
| onchain_event | decoded log | network (snake_case), contract, events (viem signature strings) |
Every task receives { env, fetch, callTask, logEvent, evm, collection }. Secrets flatten into context.env — there is no separate secrets namespace. See /compose-reference for the full API.
Two kinds:
evm.wallet({ name: "updater" }). Hosted by Goldsky, gas-sponsored by default. Cannot be used in plain local dev — use compose dev --fork-chains or switch to a BYO EOA.evm.wallet({ privateKey: env.MY_KEY, sponsorGas: true }). Gas sponsorship is OFF by default for BYO EOA wallets; opt in explicitly.List names in the manifest's secrets: array, set values with goldsky compose secret set --name X --value Y (or compose secret sync to upload .env). Values flatten into context.env at runtime. Names must be SCREAMING_SNAKE_CASE.
Bundler fallback: Alchemy → Pimlico → Gelato. Broad EVM coverage (mainnet + testnet); see /compose-reference for the chain list and caveats.
Every deployed app has a dashboard at https://app.goldsky.com/<project_id>/dashboard/compose/<app-name>.
Inline worked examples. Start with Cron → writeContract if you don't know which applies.
Exactly the minimal task above — a cron task that writes to a contract every hour, with onReorg: replay for safety.
# compose.yaml (task entry)
- name: manual_fire
path: src/tasks/manual-fire.ts
triggers:
- type: http
authentication: auth_token
// src/tasks/manual-fire.ts
import type { TaskContext } from "compose";
export async function main({ logEvent }: TaskContext, params: { amount: number }) {
await logEvent({ code: "fired", message: "manual", data: params });
return { ok: true, received: params.amount };
}
Invoke: curl -X POST -H "Authorization: Bearer $TOKEN" -d '{"amount": 42}' https://<app-url>/tasks/manual_fire.
- name: on_transfer
path: src/tasks/on-transfer.ts
triggers:
- type: onchain_event
network: polygon_amoy
contract: "0xYourContract"
events:
- "Transfer(address,address,uint256)"
import type { TaskContext } from "compose";
export async function main(
{ evm, logEvent }: TaskContext,
params: { log: { topics: string[]; data: string; address: string } },
) {
const decoded = await evm.decodeEventLog(
[{ type: "event", name: "Transfer", inputs: [/* ABI inputs */] }],
params.log,
);
await logEvent({ code: "transfer", message: "seen", data: decoded });
}
const wallet = await evm.wallet({ name: "my-oracle" }); // sponsorGas defaults TRUE
const tx = await wallet.writeContract(
evm.chains.base,
env.FEED_ADDRESS,
"setPrice(uint256)",
[1234n],
);
const wallet = await evm.wallet({
privateKey: env.MY_KEY,
sponsorGas: true, // MUST opt in; defaults FALSE
});
const runs = await collection<{ id: string; ts: number }>("runs");
await runs.setById("latest", { id: "latest", ts: Date.now() });
const recent = await runs.findOne({ ts: { $gt: Date.now() - 86_400_000 } });
Drop an ABI into src/contracts/Oracle.json. After goldsky compose codegen (or any init/dev/deploy), the contract is available as evm.contracts.Oracle. Full workflow in /compose-reference.
Only activate when Bash is available.
goldsky project list 2>&1. If not logged in, use /auth-setup.
From the user's natural-language prompt, derive as many of these as possible before asking:
polygonAmoy, base) → use it; "testnet" with no name → ask.sponsorGas: true.api_version — default to stable unless user asks otherwise.Only ask the user for fields you couldn't derive.
goldsky compose init <name>. Inspect the scaffold to see the canonical file layout.
Replace the scaffold's task block with the derived trigger + secret list. Use the YAML snippets from the Capability Tour above.
Replace the scaffold's task file with logic derived from the prompt. Use the capability-tour snippet for the chosen trigger as the starting point.
compose.yaml's secrets: → goldsky compose secret set --name X --value Y (or add to .env + compose secret sync).goldsky compose wallet create --name <name>. Then wallet list to get the address and share with the user (they may need to grant it onchain permissions on the target contract)..env (SCREAMING_SNAKE_CASE name), reference via env.X in the task.goldsky compose dev. Smart wallets require --fork-chains locally; use a BYO EOA if the user wants to test against a live testnet. For HTTP tasks: goldsky compose callTask <name> '<json>' in another terminal.
goldsky compose deploy. Expect progress: "Building Dedicated app database…" → "Deploying app…" → "Provisioning infra…" (can take a minute or two on first deploy).
goldsky compose status --json # expect .status == "RUNNING"
goldsky compose logs -f # expect app-specific log lines
Share the dashboard URL: https://app.goldsky.com/<project_id>/dashboard/compose/<app-name>.
compose dev — use --fork-chains or switch to a BYO EOA for local iteration.sponsorGas: true..env automatically. Run compose secret sync or compose deploy --sync-env.api_version is required for deploy. Default to stable./compose-doctor — Diagnose and fix broken Compose apps./compose-reference — Manifest, CLI, TaskContext API, wallets, gas sponsorship, codegen./auth-setup — goldsky login walkthrough./secrets — Generic secret management.development
Turbo pipeline YAML reference and architecture guide. Covers: YAML field syntax (start_at, from, version, primary_key), source/transform/sink configuration, validation errors, resource sizing (xs–xxl), architecture decisions (dataset vs kafka, streaming vs job, fan-out vs fan-in, sink selection, pipeline splitting). Triggers on: 'what does field X do', 'what fields does a postgres sink need', 'what resource size', 'should I use kafka or dataset', 'how to structure my pipeline'. For writing transforms, use /turbo-transforms. For end-to-end building, use /turbo-builder.
tools
Build and deploy new Goldsky Turbo pipelines from scratch. Triggers on: 'build a pipeline', 'index X on Y chain', 'set up a pipeline', 'track transfers to postgres', or any request describing data to move from a chain/contract to a destination (postgres, mysql, clickhouse, kafka, pubsub, s3, sqs, webhook). Covers the full workflow: requirements → dataset selection → YAML generation → validation → deploy. Not for debugging (use /turbo-doctor) or syntax lookups (use /turbo-pipelines).
development
Write SQL, TypeScript, and dynamic table transforms for Turbo pipelines. Covers: decoding EVM logs with _gs_log_decode, filtering/casting blockchain data, UNION ALL for combining events, TypeScript/WASM transforms (invoke function), dynamic lookup tables (dynamic_table_check), transform chaining, and Solana decoding. Triggers on: 'decode Transfer events', 'write a SQL transform', 'filter by contract', 'TypeScript transform', 'dynamic table', 'UNION ALL'. For pipeline YAML structure, use /turbo-pipelines. For end-to-end building, use /turbo-builder.
tools
Use this skill when a user wants to store, manage, or work with Goldsky secrets — the named credential objects used by pipeline sinks. This includes: creating a new secret from a connection string or credentials, listing or inspecting existing secrets, updating or rotating credentials after a password change, and deleting secrets that are no longer needed. Trigger for any query where the user mentions 'goldsky secret', wants to securely store database credentials for a pipeline, or is working with sink authentication for PostgreSQL, Neon, Supabase, ClickHouse, Kafka, S3, Google Cloud Pub/Sub, Elasticsearch, DynamoDB, SQS, OpenSearch, or webhooks.