> ## 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.

# Wallets and Secrets

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](./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.

<Note>
  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](./deploy-monitor) for details.
</Note>

### Examples

```typescript theme={null}
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.

<Note>
  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`).
</Note>

#### 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.

```bash .env theme={null}
# Compose Local Secrets
PRIVATE_KEY=132981234adsufyadsf78134asdf
```

#### Manage Secrets for Cloud

To add or update a secret in the cloud:

```bash theme={null}
goldsky compose secret set MY_PRIVATE_KEY --value xyz123
```

To update a secret and immediately redeploy so the app picks it up:

```bash theme={null}
goldsky compose secret set MY_PRIVATE_KEY --value xyz123 --redeploy
```

To remove a cloud secret:

```bash theme={null}
goldsky compose secret delete MY_PRIVATE_KEY
```

To list all secrets for the app:

```bash theme={null}
goldsky compose secret list
```

You can also write secrets into your local `.env` with the same command by adding `--env local`:

```bash theme={null}
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.

```bash theme={null}
goldsky compose deploy --sync-env
```

<Note>
  A running app only picks up new secret values after a redeploy. Use `--redeploy` on `secret set`, or run `goldsky compose deploy` yourself.
</Note>

#### Using Secrets

For secrets to be injected into your app at runtime, they have to be listed in the `secrets:` section of the [manifest](./app-configuration). 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.

```yaml compose.yaml highlight={2-5} theme={null}
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:

```typescript highlight={4,11,16} theme={null}
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}`);
}
```
