comet_prod_cron.sh is a production cron script that drives activity on the Comet JAM dApp by automatically:
- Creating jams on L2.
- Appending entries to each jam from different accounts.
- Withdrawing ETH from one participant.
- Deposit‑minting a Comet NFT via the EtherPortal.
It inspects existing state before choosing new jam IDs, so it can be safely re‑run without colliding with previously created jams.
-
Discovers the next jam ID
- Calls the Cartesi inspect API (
alljams) viaINSPECT_URL(default:https://base-sepolia.rollups.cartesi.io/v2/inspect/comet). - Parses the response, finds the maximum existing
id, and computes:START_JAM_ID = maxId + 1(or0if no jams exist).
- This keeps newly created jams, their names, and append/mint IDs aligned with the backend.
- Calls the Cartesi inspect API (
-
Runs a time‑slotted schedule
- Uses discrete time slots, one every
CREATE_INTERVALseconds. - Per jam:
- Create at slot
S. - First append at
S + APPEND_SLOTS. - Second append + withdraw + mint at
S + 2 * APPEND_SLOTS.
- Create at slot
JAM_COUNTcontrols how many jams are created in a run; the script exits after all scheduled actions complete.
- Uses discrete time slots, one every
-
Creates jams with fixed parameters
- Name:
Comet #<id>. - Description:
Automated test Comet <id> (prod check). mintPrice = 0.001ETH.maxEntries = 4.- A genesis entry is included at creation time.
- Name:
-
Appends entries and mints
- Each jam receives:
- 1 genesis entry from the creator account.
- 1 append from a second account.
- 1 append from a third account.
- After the second append, the script:
- Sends an
eth.withdrawrequest for 0.1 ETH from the first appender. - Sends an EtherPortal
depositEthercall with ajam.mintexec payload and value0.2ETH (or0.0001ETH in the JS cron).
- Sends an
- Each jam receives:
-
Rotates three accounts
- Uses
ACCOUNT1_PK,ACCOUNT2_PK,ACCOUNT3_PK. - For each jam:
- One account is the creator.
- One is the first appender.
- One is the second appender and minter.
- The assignment rotates by jam index (
slot % 3), spreading activity across the three addresses.
- Uses
-
Configuration loading
- Optionally sources
cronjob.envfrom:- The same directory as
comet_prod_cron.sh, or - One directory above.
- The same directory as
- This file is for local/dev runs only.
- In production, all environment variables should be provided by the platform (e.g. Fly.io secrets); the script does not require
cronjob.envto exist.
- Optionally sources
-
Required environment variables
- The script enforces, at startup:
RPC_URL– L1 RPC endpoint (e.g. Base Sepolia).INPUT_BOX_ADDRESS– Cartesi InputBox contract.APPLICATION_ADDRESS– Comet application address.ETHER_PORTAL_ADDRESS– EtherPortal contract.ACCOUNT1_PK,ACCOUNT2_PK,ACCOUNT3_PK– three EOA private keys (with or without0x, normalized by the script).
- Optional / tunable:
JAM_COUNT(default5).CREATE_INTERVAL(default900seconds).SLEEP_BETWEEN_STEPS(default1800seconds).INSPECT_URL(defaulthttps://base-sepolia.rollups.cartesi.io/v2/inspect/comet).
- The script enforces, at startup:
-
Inspect‑based
START_JAM_ID- If
START_JAM_IDis not set in the environment:- The script calls
get_next_jam_id, which:POSTs"alljams"toINSPECT_URL.- Decodes the hex payload to JSON.
- Computes
nextJamId = max(jams[].id) + 1(or0if there are no jams).
START_JAM_IDis then set to this value for the run.
- The script calls
- If
START_JAM_IDis set, the script logs that it is using the provided value and skips inspect.
- If
-
Slot loop
- Computes:
APPEND_SLOTS = SLEEP_BETWEEN_STEPS / CREATE_INTERVAL.TOTAL_SLOTS = JAM_COUNT + 2 * APPEND_SLOTS.
- For each
slotfrom0toTOTAL_SLOTS - 1:- Logs the slot number and virtual time.
- Performs create / append / withdraw / mint actions as their respective slot thresholds are reached.
- Sleeps
CREATE_INTERVALseconds between slots (except after the final slot).
- Computes:
- Create a
cronjob.envfile:- Start from
cronjob.env.example. - Fill in RPC URL, contract addresses, and test private keys.
- Start from
- Run the script from the repo root:
./comet_prod_cron.sh- The script will:
- Source
cronjob.envif present. - Validate required environment variables.
- Inspect current jams to choose the next
START_JAM_ID. - Create and manage
JAM_COUNTjams on a timed schedule.
- Source
- Do not rely on
cronjob.envin production. - Configure all required environment variables securely via your platform’s env/secret mechanism.
- Schedule or trigger:
./comet_prod_cron.sh- Each run:
- Reads configuration from the process environment.
- Inspects the Comet machine to determine the next jam ID.
- Executes the create/append/withdraw/mint lifecycle for
JAM_COUNTjams, then exits.
This repo includes a Dockerfile that:
- Installs dependencies:
bash,curl,jq,xxd,ca-certificates- Foundry (
cast) viafoundryup
- Copies the cron script into
/app:comet_prod_cron.sh
- Sets the entrypoint to:
bash /app/comet_prod_cron.shThe container runs the cron script once and exits after the scheduled JAM lifecycle completes.
A minimal fly.toml is provided:
- App name:
comet-cronjob(change if needed). - Primary region:
iadby default (change to your preferred region). - Processes:
[processes]
cron = "bash /app/comet_prod_cron.sh"There are no HTTP services defined; this app is intended to be run as a job/cron rather than a long-lived web service.
Set the same required variables as the script expects, but via Fly secrets:
RPC_URLINPUT_BOX_ADDRESSAPPLICATION_ADDRESSETHER_PORTAL_ADDRESSACCOUNT1_PKACCOUNT2_PKACCOUNT3_PK
Optional tunables:
JAM_COUNTCREATE_INTERVALSLEEP_BETWEEN_STEPSINSPECT_URLSTART_JAM_ID(to override inspect-based derivation)
Example:
fly secrets set \
RPC_URL="https://..." \
INPUT_BOX_ADDRESS="0x..." \
APPLICATION_ADDRESS="0x..." \
ETHER_PORTAL_ADDRESS="0x..." \
ACCOUNT1_PK="..." \
ACCOUNT2_PK="..." \
ACCOUNT3_PK="..."From the repo root:
fly deployThis will:
- Build the Docker image using
Dockerfile. - Deploy it as the
comet-cronjobapp (or whatever app name you configure).
Use Fly Machines cron to run the job on a schedule. For example, to run hourly:
fly cron schedule comet-prod-cron "0 * * * *" \
--process "cron" \
--command "bash /app/comet_prod_cron.sh"comet-prod-cronis the cron schedule name (not the app name).--process "cron"matches thecronprocess infly.toml.--commandoverrides the default entrypoint if desired (you can omit it sinceENTRYPOINTalready runs the script).
Each scheduled run:
- Starts a Machine using the current image.
- Executes the cron script once.
- Exits when the script finishes the JAM lifecycle.