Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.goldsky.com/llms.txt

Use this file to discover all available pages before exploring further.

Most Compose apps need some form of credential — an EOA private key, an auth token for an external service, etc. Compose handles both built-in smart wallets and arbitrary user-managed secrets.

Wallets

Many compose apps will need to make blockchain transactions and will need gas and payment funds to do so. By default, Compose will make you a smart wallet which allows you to pay gas fees in fiat as part of your normal monthly Goldsky bill. This allows simple USD based accounting for companies and users who are not “blockchain-native”. You can easily fund these smart wallets with any tokens you may require for your particular business logic (by default Goldsky will pay gas fees if you haven’t funded the wallet yourself). Goldsky hosted wallets are created dynamically and idempotently in your app code, allowing any type of logic in wallet creation — for specifics see Context. However there may be times when specific EOA wallets are needed for specific transactions, such as owner-only contract methods. In those cases you can store your private key securely in a secret — see below for details.
To fund your built-in smart wallet (beyond Goldsky’s default gas-sponsorship behavior), you can retrieve its public key from the compose Dashboard at app.goldsky.com. See monitoring for details.

Examples

import { TaskContext } from "compose";

export async function main({ env, evm }: TaskContext) {

  // a default smart wallet
  // this will make a smart wallet and will sponsor gas by default
  const mySmartWallet = await evm.wallet({ name: "my-wallet" });

  // you can disable gas sponsoring on a smart wallet
  // allowing you to obtain the public key from your compose dashboard and fund it yourself
  const mySelfFundedSmartWallet = await evm.wallet({ 
    name: "my-wallet", 
    sponsorGas: false 
  });

  // make an EOA based wallet using a private key secret 
  // by default privateKey wallets don't use gas sponsoring
  // see below for info about storing the secret
  const myPrivateKeyWallet = await evm.wallet({ 
    privateKey: env.MY_PRIVATE_KEY 
  });
}

Secrets

Compose secrets are scoped to a specific Compose app within your Goldsky project. You can set or update secrets at any time using the CLI, but a running app will only pick up new secret values after a redeploy. This protects running apps from accidental changes and lets you roll forward (or back) safely by pairing a deploy with the secrets it expects. The way secrets are managed in the cloud vs locally is slightly different.
Secret names must be in SCREAMING_SNAKE_CASE — all uppercase letters, digits, and underscores, starting with a letter (e.g. MY_SECRET, API_KEY_V2).

Manage Secrets for Local Dev

In local dev, you’ll put your secrets in your .env file. Every compose app created with goldsky compose init comes with a gitignored .env file by default.
.env
# Compose Local Secrets
PRIVATE_KEY=132981234adsufyadsf78134asdf

Manage Secrets for Cloud

To add or update a secret in the cloud:
goldsky compose secret set MY_PRIVATE_KEY --value xyz123
To update a secret and immediately redeploy so the app picks it up:
goldsky compose secret set MY_PRIVATE_KEY --value xyz123 --redeploy
To remove a cloud secret:
goldsky compose secret delete MY_PRIVATE_KEY
To list all secrets for the app:
goldsky compose secret list
You can also write secrets into your local .env with the same command by adding --env local:
goldsky compose secret set MY_PRIVATE_KEY --value xyz123 --env local

Syncing .env to the cloud at deploy

If you’ve been developing locally with secrets in your .env file, compose deploy --sync-env uploads every entry from your .env as a cloud secret before deploying. This is a convenient way to push a whole app’s secrets in one step.
goldsky compose deploy --sync-env
A running app only picks up new secret values after a redeploy. Use --redeploy on secret set, or run goldsky compose deploy yourself.

Using Secrets

For secrets to be injected into your app at runtime, they have to be listed in the secrets: section of the manifest. Only secrets named in the manifest of the currently-deployed version are made available to your tasks — so older deploys keep working even as you add, rename, or remove secrets for newer ones.
compose.yaml
name: "my_app"
secrets:
  - MY_PRIVATE_KEY
  - MY_API_KEY
  - CONTRACT_ADDRESS
tasks:
  - name: "price_fetcher"
    path: "./tasks/fetch_price.ts"
  - name: "data_processor"
    path: "./tasks/process_data.ts"
Inside a task, each secret is exposed on ctx.env under its exact name:
import { TaskContext } from "compose";

export async function main({ env, evm, fetch }: TaskContext) {
  const myPrivateKeyWallet = await evm.wallet({ privateKey: env.MY_PRIVATE_KEY });

  const address = "0x1234567890abcdef1234567890abcdef12345678" as `0x${string}`;
  const questionId = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd";

  const { hash } = await myPrivateKeyWallet.writeContract(
    evm.chains.polygon,
    env.CONTRACT_ADDRESS as `0x${string}`,
    "prepareCondition(address,bytes32,uint256)",
    [address, questionId, 2]
  );

  const response = await fetch(`https://api-service/api/v1/path?auth_token=${env.MY_API_KEY}`);
}