L1 Contract Interactions
Transactions related to Cartesi applications are sent directly to the base layer (L1) as regular contract interactions with the Cartesi Rollups smart contracts.
Instead of providing custom actions, this library exports typed ABIs and deployment addresses of all Cartesi Rollups contracts through the @cartesi/client/abi entrypoint, to be used with viem's own contract actions, like writeContract, readContract, simulateContract and estimateContractGas.
Sending inputs
Send a generic input to an application through the InputBox contract.
import { , } from "viem";
import { } from "viem";
import { , } from "@cartesi/client/abi";
import { } from "viem/accounts";
import { } from "viem/chains";
const = ("0x...");
const = ({
,
: ,
: (),
});
const = await .({
: ,
: ,
: "addInput",
: ["0x...", ("hello")],
});Depositing assets
Deposit assets to an application through one of the asset portals.
Depositing Ether through the EtherPortal:
import { , , } from "viem";
import { } from "viem";
import { , } from "@cartesi/client/abi";
import { } from "viem/accounts";
import { } from "viem/chains";
const = ("0x...");
const = ({
,
: ,
: (),
});
const = await .({
: ,
: ,
: "depositEther",
: ["0x...", ("hello")],
: ("1"),
});Depositing ERC-20 tokens through the Erc20Portal. The portal must have an allowance to transfer the tokens on behalf of the depositor, so an approve call to the token contract is required beforehand:
import { , , } from "viem";
import { } from "viem";
import { , } from "@cartesi/client/abi";
import { } from "viem/accounts";
import { } from "viem/chains";
const = ("0x...");
const = ({
,
: ,
: (),
});
const = "0x..." as ;
const = ("1", 18);
const = await .({
: ,
: ,
: "approve",
: [, ],
});
const = await .({
: ,
: ,
: "depositErc20Tokens",
: [, "0x...", , "0x"],
});Deposits of ERC-721 and ERC-1155 tokens follow the same pattern, using erc721PortalAbi / erc721PortalAddress (function depositErc721Token), erc1155SinglePortalAbi / erc1155SinglePortalAddress (function depositSingleErc1155Token) and erc1155BatchPortalAbi / erc1155BatchPortalAddress (function depositBatchErc1155Token).
Executing outputs
Outputs (vouchers) are executed through the application contract itself.
The toOutputArgs utility converts an Output returned by the Cartesi node API into the arguments expected by IApplication.executeOutput.
import { } from "viem";
import { } from "viem";
import { , } from "@cartesi/client";
import { } from "@cartesi/client/abi";
import { } from "viem/accounts";
import { } from "viem/chains";
const = ("0x...");
const = "0x...";
const = ({
: ("http://127.0.0.1:6751/rpc"),
});
const = ({
,
: ,
: (),
});
// output with proof, returned by the Cartesi node
const = await .({
,
: 1n,
});
const = await .({
: ,
: ,
: "executeOutput",
: (),
});toOutputArgs throws if the output has no proof yet (outputHashesSiblings).
Validating outputs
An output can be validated without executing it, using the validateOutput view method of the application contract.
import { } from "viem";
import { } from "viem";
import { , } from "@cartesi/client";
import { } from "@cartesi/client/abi";
import { } from "viem/chains";
const = "0x...";
const = ({ : , : () });
const = ({
: ("http://127.0.0.1:6751/rpc"),
});
const = await .({
,
: 1n,
});
// reverts if the output is not valid
await .({
: ,
: ,
: "validateOutput",
: (),
});Recovering a tournament bond
Applications running under PRT settle disputes in tournaments. A commitment's bond becomes claimable once its tournament is finished, and tryRecoveringBond takes no arguments and is not restricted, so any account can send it.
A tournament is created per dispute by MultiLevelTournamentFactory, so there is no published address to import: you hold the address the node reports and call it through iTournamentAbi.
Whether there is anything to claim is current contract state, which the node reports on the tournament's snapshot. bondRecovery.disposition is RECOVERABLE when a bond is waiting, and claimer and payment are filled in only then — a payment of zero is a real value, not an absence.
import { } from "viem";
import { , } from "viem";
import { } from "@cartesi/client";
import { } from "@cartesi/client/abi";
import { } from "viem/accounts";
import { } from "viem/chains";
const = ("0x...");
const = "0x...";
const = ({ : , : () });
const = ({
: ("http://127.0.0.1:6751/rpc"),
});
const = ({
,
: ,
: (),
});
const = await .({
,
: "0x...",
});
if (... === "RECOVERABLE") {
const { } = await .({
: ,
: .,
: "tryRecoveringBond",
,
});
const = await .();
}PRT contract addresses
Most Cartesi contracts are deployed at the same address on every chain, so their exports are a single address. DaveAppFactory and MultiLevelTournamentFactory are not: dave deploys them per chain, because the tournament parameters depend on the chain's block time. Their address exports are records keyed by chain ID.
import { } from "@cartesi/client/abi";
import { } from "viem/chains";
const = [.];The records cover the eight public chains plus the devnet (31337). dave publishes no deployment for cannon (13370), so there is no entry for it.
Estimating gas
Gas estimation is done with viem's estimateContractGas action.
Note that viem already estimates gas automatically when sending a transaction without an explicit gas value.
import { , } from "viem";
import { } from "viem";
import { , } from "@cartesi/client/abi";
import { } from "viem/chains";
const = ({ : , : () });
const = await .({
: ,
: ,
: "addInput",
: ["0x...", ("hello")],
: "0x...",
});