Skip to main content
Many Compose APPs will need some secrets, whether it’s EOA wallets, or auth tokens for interacting with external services, we’ve got you covered.

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 will be needed for specific transactions such as on owner-only contract methods. In these 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 bound to the particular Compose App and are immutable once an app is deployed. To have a running app pick up new secrets values, you’ll need to redeploy This protects apps from accidental mistakes with secrets and enables versioning of secrets when the code changes need to be synced. The methodology for how secrets are managed in the cloud vs locally is slightly different.

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 will come with a gitignored .env file by default.

Example

# Compose Local Secrets
PRIVATE_KEY=132981234adsufyadsf78134asdf

Manage Secrets for Cloud

To add or update a secret run
goldsky compose secret set MY_PRIVATE_KEY xyz123
To remove a secret run
goldsky compose secret delete MY_PRIVATE_KEY

Using Secrets

In order for secrets to be injected into your app at runtime, they’ll need to be referenced in the secrets section of the manifest. This allows you to reference different secrets for different iterations of your app, without deleting previous versions allowing safe roll forwards and roll backs.

Example

name: "my_app"
secrets:
  - MY_PRIVATE_KEY 
  - MY_API_KEY
tasks:
  - name: "price_fetcher"
    path: "./tasks/fetch_price.ts"
  - name: "data_processor"
    path: "./tasks/process_data.ts"
Then in your task you can access the secrets like this:
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}`);
}