Skip to main content
Compose allows you to interact with smart contracts with type safety and flexible wallet options. See wallets for details on the different types of wallets. We also have some built-in contract support for common interfaces like erc20.

Code Gen

In order to interact with smart contracts, you put your ABI files into a “/contracts” folder. Then when you run goldsky compose codegen, we’ll generate typed contract classes that you can use like so:
/// <reference types="../../.compose/types.d.ts" /> 

// access the class you generated in the steps above
import { BitcoinOracleContract } from "../.compose/generated";

export async function main(
  { evm, env }: TaskContext,
  _args: any
) {
  const wallet = await env.wallet();

  const response = await fetch<{ bitcoin: { usd: number } }>(
    "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
  );

  // Convert timestamp and price to bytes32 format
  const timestampAsBytes32 = `0x${timestamp.toString(16).padStart(64, '0')}`;
  const priceAsBytes32 = `0x${Math.round(bitcoinPrice * 100).toString(16).padStart(64, '0')}`;

  const bitcoinOracleContract = new BitcoinOracleContract(env.ORACLE_ADDRESS, evm.chains.base, wallet);

  // execute the "write" method
  await bitcoinOracleContract.write.write(
    timestampAsBytes32, 
    priceAsBytes32,
    { 
      confirmations: 3, // this will not resolve the promise until the transaction has been seen in 3 blocks
      onReorg: {
        // this will replay the transaction with new nonce and new gas if it's reorged later on after the three confirmations have passed
        // see "Reorg Handling" for more info
        type: "replay", 
      }
    }
  );

  // simulate the "write" method
  await bitcoinOracleContract.write.simulate(
    timestampAsBytes32, 
    priceAsBytes32
  );

  // read a "getLatestPrice" view method
  const { price, time } = await bitcoinOracleContract.getLatestPrice.read();
}

Wallet Methods

You can also interact with contracts without generating an instance of a contract class or having to obtain a full ABI. If you know the address and signature of the smart contract method, then you can call it directly with your wallet. Read more here.
/// <reference types="../../.compose/types.d.ts" /> 

export async function main(
  { evm, env }: TaskContext,
  _args: any
) {
  const wallet = await evm.wallet();

  const { hash } = await wallet.writeContract(
    evm.chains.polygon,
    env.CONTRACT_ADDRESS,
    "reportPayouts(bytes32,uint256[])",
    [resultId, payouts],
  );
}