# TypeScript scripts

> Hosted TypeScript with @ftw/sdk for what Flowscript and workflow steps don't do: outside APIs, signals, actions other scripts call, and bespoke logic, sandboxed and held to a policy you approve.

A script is TypeScript that belongs to a project and runs on ftw.trade, in a sandbox: QuickJS in WebAssembly, a fresh runtime each run. No Node, no filesystem, no network except to hosts its policy names, and never a wallet key.

There are three kinds:

| Kind | Made with | Does |
|---|---|---|
| Automation | `automation()` | Runs on triggers and trades through wallet handles |
| Source | `source()` | Publishes typed events. See [Sources](https://docs.ftw.trade/sources/other-sources#typescript-sources) |
| Action | `action()` | A function other scripts and workflows call by name, with typed arguments and answer |

## An automation

```ts
import { automation } from '@ftw/sdk';

export default automation({
  name: 'Dip buyer',
  triggers: [{ pool: 'base:0x…', below: 0.0021 }, { every: '5m' }],
  policy: { wallets: ['w1'], maxEthPerTrade: 0.05, maxEthPerDay: 0.2 },
  async run(ctx, event) {
    if (event.type !== 'price') return;
    const fill = await ctx.wallets.get('w1').buy({ token: '0x…', eth: 0.05 });
    ctx.log.info('bought the dip', fill);
    ctx.metric('price', event.price);
  },
});
```

## Triggers

- `{ every: "1s" … "7d" }` on a schedule;
- `{ pool, above?, below? }` when a price crosses a line;
- `{ signal, where? }` on a source's events;
- `{ socket }` on a websocket's messages;
- and always by hand.

## The policy

You approve a script's policy when you deploy it, and every call is checked against it:

| Field | Limits |
|---|---|
| `wallets` | Which wallets it may trade (none means read-only) |
| `maxEthPerTrade`, `maxEthPerDay` | How much it may spend |
| `tokens` | Which tokens it may touch |
| `egress` | Which hosts `ctx.fetch` may reach |
| `secrets` | Which of your secrets it may use (as `{{secrets.NAME}}` in a request, never as a value it can read) |
| `live` | Whether it may trade a live project |
| `bridge` | The most one move may bridge |

## What a script can do

`ctx.wallets.get(id)` buys, sells, bridges and reads balances; `ctx.pools` reads prices, candles, swaps and liquidity; `ctx.fetch` calls allowed hosts; `ctx.state` keeps 64 KB between runs; `ctx.signal` and `ctx.emit` publish; `ctx.actions.call` calls an action; `ctx.log` and `ctx.metric` report.

Every effect (a buy, a bridge, an outside call, a signal) is journaled per delivery, so a run that's retried never repeats one.

## Versions and deploys

Each save is a version; deploying one asks you to approve its policy. Push from your machine with `ftw-trade push src/*.ts --project <id> --deploy`. Every run's log, metrics and emitted rows are kept, and a project's dashboards can chart them.

## Flowscript, workflow or script?

| You want to | Use |
|---|---|
| Decide on bars and trade | A Flowscript strategy |
| Do things in order when something happens | A workflow |
| Filter or transform a stream | A Flowscript source |
| Call an outside API, or anything bespoke | A script |
