Automate

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:

KindMade withDoes
Automationautomation()Runs on triggers and trades through wallet handles
Sourcesource()Publishes typed events. See Sources
Actionaction()A function other scripts and workflows call by name, with typed arguments and answer

An automation#

TypeScript
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:

FieldLimits
walletsWhich wallets it may trade (none means read-only)
maxEthPerTrade, maxEthPerDayHow much it may spend
tokensWhich tokens it may touch
egressWhich hosts ctx.fetch may reach
secretsWhich of your secrets it may use (as {{secrets.NAME}} in a request, never as a value it can read)
liveWhether it may trade a live project
bridgeThe 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 toUse
Decide on bars and tradeA Flowscript strategy
Do things in order when something happensA workflow
Filter or transform a streamA Flowscript source
Call an outside API, or anything bespokeA script