SkillAgentSearch skills...

Tuktuk

Permissionless crank turner on Solana

Install / Use

/learn @helium/Tuktuk
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

TukTuk

Run your permissionless cranks on Solana

TukTuk

Table of Contents

Introduction

Tuktuk is a permissionless crank service. If you have a Solana smart contract endpoint that needs to be run on a trigger or specific time, you can use tuktuk to run it. Endponts need to be more or less permissionless, though you can have tuktuk provide PDA signatures.

Tuktuk's architecture allows for crankers to run a simple rust util that requires only a working solana RPC url and very minimal dependencies. There is no dependency on geyser, yellowstone, or any other indexing service.

Creators of Task Queues set their payment per-crank turn in SOL. Crankers that run the tasks are paid out in SOL for each crank they complete. There is a minimum deposit of 1 SOL to create a task queue to discourage spam. This deposit is refunded when the task queue is closed. The intent is to minimize the number of task queues that crank turners need to watch. You should try to reuse task queues as much as possible. It is an antipattern to create a new task queue for each user, for example.

Running a Crank Turner

Install the crank turner:

cargo install tuktuk-crank-turner

If you want to run a crank turner, create a config.toml file with the following:

rpc_url = "https://api.mainnet-beta.solana.com"
key_path = "/path/to/your/keypair.json"
min_crank_fee = 10000

Then run the crank turner:

tuktuk-crank-turner -c config.toml

You can also provider configuration via environment variables

export TUKTUK__RPC_URL="https://api.mainnet-beta.solana.com"
export TUKTUK__KEY_PATH="/path/to/your/keypair.json"
export TUKTUK__MIN_CRANK_FEE=10000
tuktuk-crank-turner

Requirements

You will need a good Solana RPC that doesn't have heavy rate limits (for when there are a lot of tasks queued). You should also handle restarting the process if it crashes, as this can happen if your RPC disconnects the websocket without a proper handshake.

Usage

First, you'll want to install the tuktuk-cli. The cli is great for debugging and managing your task queue.

Prerequisites

Make sure you are on rustc 1.85:

rustup install 1.85
rustup default 1.85

Make sure you also have openssl installed:

brew install openssl

Installation

Install the tuktuk cli by running:

cargo install tuktuk-cli

Quickstart

For quick examples of how to queue tasks and crons using tuktuk in typescript, see the typescript-examples folder.

Create a task queue

First, you'll need to get some SOL to fund the task queue. You can get SOL from Jupiter Aggregator.

Next, create a task queue. A task queue has a default crank reward that will be used for all tasks in the queue, but each task can override this reward. Since crankers pay sol (and possibly priority fees) for each crank, the crank reward should be higher than the cost of a crank or crankers will not be incentivized to run your task.

Note that the funding-amount you specify is not inclusive of the 1 SOL minimum deposit. The funding amount will be used to pay the fees for tasks queued recursively (ie, by other tasks).

tuktuk -u <your-solana-url> task-queue create --name <your-queue-name> --capacity 10 --funding-amount 100000000 --queue-authority <the-authority-to-queue-tasks> --crank-reward 1000000

The queue capacity is the maximum number of tasks that can be queued at once. Higher capacity means more tasks can be queued, but it also costs more rent in SOL.

Closing a Task Queue

You can close a task queue by using the task-queue close command. This will refund the 1 SOL deposit and the funding amount.

First, close any queue authorities:

tuktuk -u <your-solana-url> task-queue remove-queue-authority --task-queue-name <your-queue-name> --queue-authority <your-wallet-address>

Then, close the task queue:

tuktuk -u <your-solana-url> task-queue close --task-queue-name <your-queue-name>

Funding a Task Queue

Generally, tasks are funded by the wallet that creates the task. The only exception is for tasks that schedule more tasks.

If your task queue has any tasks that themselves queue tasks, you will need to keep it funded. This is because the task queue uses its own sol to fund recursively queued tasks. Note that you will not need to fund the task queue immediately if you specified a funding-amount in the create command.

tuktuk -u <your-solana-url> task-queue fund --task-queue-name <your-queue-name> --amount 100000000

Adding Queue Authorities

Task queues are meant to be reused for multiple use cases. As such, there can be multiple wallets that have the authority to queue tasks. Note that this authority should not be given out blindly, as the authority can queue tasks that use up task queue funding, and can use the task queue's custom signers.

You can add queue authorities to a task queue by using the add-queue-authority command. Queue authorities can queue tasks on behalf of other users.

tuktuk -u <your-solana-url> task-queue add-queue-authority --task-queue-name <your-queue-name> --queue-authority <the-authority-to-queue-tasks>

An example use case for multiple authorities at Helium is that we have a program, hpl-crons, that allows users to create specific jobs that automate helium tasks relating to things like their staked positions. Because we have audited these specific tasks, we allow a PDA signer of the hpl-crons program to queue tasks on behalf of users. Simultaneously, we also have an admin authority that can queue or remove tasks for the sake of troubleshooting.

Queue a task

You can queue a task by using the QueueTaskV0 instruction. There are many ways to call this function. You can do this via CPI in your smart contract, or you can use typescript. For examples of doing this in typescript, see the typescript-examples folder.

Similar functions are available in the tuktuk-sdk rust library. For an example of how to use this in a solana program, see the cpi-example and the corresponding tests.

Remote Transactions

Sometimes transactions are complicated enough that you cannot compile it ahead of time. An example of this may be a transaction that uses cNFTs and requires a proof. In this case, you can run a remote server that returns the set of instructions. This server will need to sign the instructions so the program can trust that they are associated with the given task.

Tuktuk will POST to the remote URL with the following JSON body:

{
  "task": "<task-pubkey>",
  "task_queue": "<task-queue-pubkey>",
  "task_queued_at": "<task-queued-at-timestamp>"
}

Your server will need to return the following JSON body:

{
  "transaction": "<base64-encoded-transaction>",
  "remaining_accounts": "<base64-encoded-remaining-accounts>",
  "signature": "<base64-encoded-signature>"
}

You can see an example of this in the remote-server-example.

You can queue such a task by using remoteV0 instead of compileV0 in the QueueTaskV0 instruction.

await program.methods.queueTaskV0({
  id: taskId,
  trigger: { now: {} },
  transaction: {
    remoteV0: {
      url: "http://localhost:3002/remote",
      signer: me,
    },
  },
});

Monitoring the Task Queue

You can monitor tasks by using the cli:

tuktuk -u <your-solana-url> task list --task-queue-name <your-queue-name> --description <prefix>

The --description flag allows you to filter by prefix on the description field of tasks. This can be useful if you have a lot of tasks in a queue and want to only view specific kinds of tasks.

Note that this will only show you tasks that have not been run. Tasks that have been run are closed, with rent refunded to the task creator.

If a task is active but has not yet been run, the cli will display a simulation result for the task. This is to help you debug the task if for some reason it is not running.

Cron Tasks

Sometimes, it's helpful to run a task on a specific schedule. You can do this by creating a cron job. A cron job will queue tasks onto a task queue at a specific time. The following example will queue a task every minute. Note that you will need to keep the cron funded so that it can, in turn, fund the task queue for each task it creates.

See an example of creating a cron job here typescript-examples.

Monitoring the Cron Job

You can list your cron jobs by using the cron list command:

tuktuk -u <your-solana-url> cron list

You can get a particular cron job by name

Related Skills

View on GitHub
GitHub Stars92
CategoryDevelopment
Updated29d ago
Forks18

Languages

Rust

Security Score

95/100

Audited on Mar 2, 2026

No findings