Migrate from Mimic Protocol
Mimic functions, in TypeScript.
Thyme Flow runs the same kind of job a Mimic function does: read the chain, decide, act on a schedule. The decision logic carries over. The language, the reads and the output change: a Flow task is plain TypeScript with viem, and it returns calls instead of intents.
- Not AssemblyScript
- TypeScript
- Sends every call
- Your Safe
- Pro plan, public pricing
- $29
01 / Mapping
Every Mimic concept has a place, or a decision.
A Mimic function reads through environment and emits intents. A Flow task reads with a viem client and returns calls. This table maps each piece, and says where there is nothing to map to.
| Mimic Protocol | Thyme Flow | Notes |
|---|---|---|
Mimic Protocolexport default function main(): void | Thyme Flowexport default defineTask({ schema, async run(ctx) { … } }) | One module per task. Add onSuccess, onFail, onSkip and onError callbacks next to run if you need them. |
Mimic Protocolinputs: in manifest.yaml | Thyme Flowctx.args, typed by a Zod schema | Arguments are validated before run. The console renders a form from the schema. inputs.chainId goes away: one executable runs on one chain. |
Mimic ProtocolGenerated ABI wrappers (mimic codegen) | Thyme Flowctx.client.readContract with a viem ABI | Use parseAbi or viem’s erc20Abi. Writes become calls built with encodeFunctionData. |
Mimic ProtocolTransferBuilder and EvmCallBuilder | Thyme Flow{ canExec: true, calls: [{ to, data }] } | A transfer is an ERC-20 transfer call. An EVM call maps one to one. Calls run in the order you return them. |
Mimic ProtocolSwapBuilder and cross-chain intents | Thyme FlowA call to a DEX router you choose | Flow does not route. A single-chain swap becomes an approve and a swap call, with the minimum output passed to the router call. Cross-chain swaps cannot be one task. |
Mimic Protocol.send(maxFee) in USD credits | Thyme FlowSponsored gas from the workspace dBank | There is no per-intent fee cap. Testnet gas is free. |
Mimic Protocolenvironment.tokenPriceQuery and .toUsd() | Thyme FlowAn on-chain price feed, or fetch with a key in ctx.secrets | There is no built-in price oracle. Pick a source and compare the results. |
Mimic Protocolenvironment.subgraphQuery | Thyme Flowfetch the subgraph endpoint | Any GraphQL endpoint works, including a subgraph hosted on Thyme Atlas. |
Mimic Protocolstorage.getData and createSetDataCall | Thyme Flowctx.storage.key = value | Plain JSON, no fee. Writes persist when the run succeeds. Existing values do not move: seed them once. |
Mimic Protocollog.info(...) | Thyme Flowctx.logger.info(...) | Captured and shown in the execution log in the console. |
| Mimic ProtocolCron trigger | Thyme FlowCron trigger | Mimic’s execution window and end date have no equivalent. Pause the executable when the schedule should end. |
| Mimic ProtocolEvent trigger | Thyme FlowAn interval trigger that polls | Keep a block cursor in ctx.storage and skip when nothing is new. Runs are no longer per event. |
| Mimic ProtocolEIP-7702 smart account | Thyme FlowYour own Safe | Flow executes through a Zodiac Roles role limited to the contracts and functions you allow. It does not use your EOA. |
02 / Code
The same function, ported.
A top-up that sends a fixed amount when a wallet’s balance runs low. The check and the transfer stay the same. The threshold is now in token units, because Flow has no built-in USD price. For a stablecoin that is the same number.
import { DenominationToken, ERC20Token, log, TokenAmount, TransferBuilder, USD } from '@mimicprotocol/lib-ts'
import { ERC20 } from './types/ERC20'
import { inputs } from './types'
export default function main(): void {
const token = ERC20Token.fromAddress(inputs.token, inputs.chainId)
const balance = new ERC20(inputs.token, inputs.chainId).balanceOf(inputs.recipient).unwrap()
const balanceUsd = TokenAmount.fromBigInt(token, balance).toUsd().unwrap()
log.info('Balance in USD: {}', [balanceUsd.toString()])
if (balanceUsd.lt(USD.fromStringDecimal(inputs.thresholdUsd))) {
const amount = TokenAmount.fromStringDecimal(token, inputs.amount)
const maxFee = TokenAmount.fromStringDecimal(DenominationToken.USD(), inputs.maxFeeUsd)
TransferBuilder.forChain(inputs.chainId)
.addTransferFromTokenAmount(amount, inputs.recipient)
.build()
.send(maxFee)
}
}import { defineTask, z } from '@thyme-labs/sdk'
import { encodeFunctionData, erc20Abi, formatUnits, parseUnits } from 'viem'
export default defineTask({
schema: z.object({
token: z.address(),
recipient: z.address(),
amount: z.string(),
minBalance: z.string(),
}),
async run(ctx) {
const { token, recipient } = ctx.args
const decimals = await ctx.client.readContract({
address: token,
abi: erc20Abi,
functionName: 'decimals',
})
const balance = await ctx.client.readContract({
address: token,
abi: erc20Abi,
functionName: 'balanceOf',
args: [recipient],
})
ctx.logger.info('Balance: ' + formatUnits(balance, decimals))
if (balance >= parseUnits(ctx.args.minBalance, decimals)) {
return { canExec: false, message: 'Balance is above the minimum' }
}
return {
canExec: true,
calls: [{
to: token,
data: encodeFunctionData({
abi: erc20Abi,
functionName: 'transfer',
args: [recipient, parseUnits(ctx.args.amount, decimals)],
}),
}],
}
},
})03 / Agent
Or let your agent port it.
Paste one prompt into Claude Code, Codex, Cursor or any other coding agent. It reads the migration skill, finds your Mimic functions and their triggers, ports them one at a time and runs each one locally before anything is uploaded.
Read https://flow.thymelabs.io/docs/skills/thyme-migrate-mimic/SKILL.md and follow it to port the Mimic Protocol functions in this repository to Thyme Flow. If you support skills, save that file as a skill named thyme-migrate-mimic. Start by listing the functions, intents and triggers you find, tell me which ones have no Flow equivalent, port one, run it locally, and ask me before uploading or scheduling anything.
The agent signs in through a pairing login you approve in your browser. Allowing contracts on your Safe, and any run that sends a transaction, stays with you.
04 / Steps
From manifest to executable.
Port one function at a time. Run it locally first, then give it a schedule, so you can check each one before it sends anything on mainnet.
- 01
Install the CLI and scaffold a task
Create a project and one task per Mimic function.
npm install -g @thyme-labs/cli thyme init my-flow-project cd my-flow-project && npm install thyme new top-up - 02
Move main into run
Swap the reads, inputs, storage and output using the table above, and return
callsinstead of building intents. Copy the values from your manifest inputs intoargs.json. - 03
Run it against the chain
Set
RPC_URLandSIMULATE_ACCOUNTin.env, then run the task. You see the decision and the calls it would send, without sending them.thyme run top-up - 04
Declare the calls it may send
Add
permissions.jsonnext to the task. Flow rejects any returned call that is not declared before it is submitted.{ "calls": [ { "target": { "arg": "token" }, "function": "transfer(address,uint256)" } ] } - 05
Upload and schedule it
Upload a release and set up a Safe profile that allows the same target and function. When you are ready for live runs, create an executable with your cron or interval. Its schedule starts automatically once provisioning and permission checks complete; approve this step before an agent creates it.
thyme upload top-up --tag v1 - 06
Check the first run
Inspect the execution log for the first scheduled run. Execute now sends an additional real run while the schedule is already active.
05 / Differences
What works differently.
Most single-chain functions port directly. These are the places where Flow makes a different choice, so check them before you switch.
Calls, not intents
Mimic emits an intent and a solver fulfils it, with the settler enforcing your limits. Flow sends the exact calls a task returns. Put a bound such as a minimum output into the call itself, for example the router’s amountOutMinimum, so the contract enforces it. A check inside the task only holds at the moment it runs.
No swap or bridge routing
Swaps go through a DEX router you call yourself, and one executable runs on one chain, so cross-chain intents cannot move over as one task.
The role limits contracts and functions, not values
Your Safe’s role allows the contracts and functions you approve. In this release it does not restrict recipients or amounts, so a task allowed to call transfer chooses both. Keep only the funds the automation needs in the Safe.
No event triggers or price oracle
Poll on a short interval with a block cursor in ctx.storage, and bring your own price source for USD thresholds.
Gas in USD from a prepaid balance
Mainnet gas is sponsored and charged to the workspace dBank, a prepaid USD balance. Testnet gas is free.
06 / FAQ
Questions
- Do I have to rewrite my Mimic function?
- Yes, in TypeScript. Mimic functions are AssemblyScript compiled to WebAssembly, which Flow does not run. The decision logic carries over, but the entry point, the reads and the output change. A single-chain function that reads balances and sends transfers or calls is usually a short port.
- Which Mimic features have no Flow equivalent?
- Swap, bridge and cross-chain intents, the solver network, the built-in token price and relevant-token queries, event triggers, and native-value transfers. The mapping table above says what to use instead where there is an option.
- Which chains does Flow support?
- Mainnet automation runs on Polygon, OP Mainnet, BNB Smart Chain, Base, Arbitrum One and Arc, where gas is paid in USDC. Ethereum Sepolia, Polygon Amoy and Unichain Sepolia are available for testing, and Arc Testnet is coming shortly. The console lists the networks enabled for your workspace. If you need another EVM chain, write to support@thymelabs.io.
- Does Thyme hold the keys to my funds?
- No owner key. With a Safe profile, Thyme runs an executor that is a member of one role on your Safe. That role only allows the contracts and functions you approve, and the executor cannot widen it or manage the Safe. You keep ownership and can remove the role at any time.
- How much does Flow cost?
- The Free plan covers testnets. Pro is $29 a month and Ultimate is $149 a month, both with mainnet access and more executables. Mainnet gas is sponsored and charged in USD to your workspace's prepaid dBank credit, so you do not keep a gas token on each chain.
- Can an AI agent do the migration?
- Yes. Copy the prompt on this page into Claude Code, Codex, Cursor or another coding agent. It reads the thyme-migrate-mimic skill, lists what has no Flow equivalent, ports one function at a time and runs it locally. You approve the login, the Safe permissions and any real transaction.
- Can you help port our functions?
- Yes. Send the function to support@thymelabs.io and we will help you port it and check the first runs.
Start here
Bring the logic. Keep your keys.
Port one Mimic function, run it locally, and schedule it from your own Safe.