> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-evm-cookbook.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Example Usage

> Learn how to interact with Sei precompiles using ethers.js to query and execute CosmWasm contracts from the EVM.

<Info>
  Under [Proposal 115](https://seistream.app/proposals/115), no new CosmWasm contracts can be deployed on Sei. The examples below apply to **pre-existing CosmWasm contracts** only. Calls to `instantiate()` revert.
</Info>

You can use the Sei precompiles like any standard smart contract on the EVM. For
example, this page uses [ethers.js](https://docs.ethers.org/v6/) to query an
existing CosmWasm contract and execute actions on it.

## Setup

To install `ethers`, run this command in a terminal in your project directory:

```bash theme={null}
npm install ethers @sei-js/precompiles@^3
```

This example uses the [CosmWasm precompile](/evm/precompiles/cosmwasm-precompiles/cosmwasm):

```typescript theme={null}
// Import Wasm precompile address and ABI
// View the source ABI: https://github.com/sei-protocol/sei-chain/tree/main/precompiles/wasmd
import { WASM_PRECOMPILE_ABI, WASM_PRECOMPILE_ADDRESS } from '@sei-js/precompiles';
```

## Using the contract

Next, set up a provider and a contract to interact with Sei:

```typescript theme={null}
import { ethers, toUtf8Bytes, toUtf8String } from 'ethers';

// Using MetaMask as the signer and provider
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();

// Create a contract with the signer
const contract = new ethers.Contract(WASM_PRECOMPILE_ADDRESS, WASM_PRECOMPILE_ABI, signer);
```

#### Querying & executing a CosmWasm contract

When you have the contract instance, you can send query and execute messages to
any CosmWasm smart contract. The example below assumes a counter contract with a
`get_count` function.

```typescript theme={null}
// Replace with your contract
const COUNTER_CONTRACT_ADDRESS = 'sei1eyf...xff';

// Query to get the count on the counter contract (replace with function from your ABI)
const queryMsg = { get_count: {} };
const queryResponse = await contract.query(COUNTER_CONTRACT_ADDRESS, toUtf8Bytes(JSON.stringify(queryMsg)));
console.log(toUtf8String(queryResponse));

// Execute message to increment the count on the contract. (Replace with any function from your ABI)
// No funds are attached since the increment method does not require sei. (Your ABI may require funds)
const executeMsg = { increment: {} };
const executeResponse = await contract.execute(
  COUNTER_CONTRACT_ADDRESS,
  toUtf8Bytes(JSON.stringify(executeMsg)),
  toUtf8Bytes(JSON.stringify([])) // Used for sending funds if needed
);

// Wait for the transaction to be confirmed
await executeResponse.wait();
console.log(executeResponse);
```

### Executing a payable function

This example executes the `donate` method on the same contract. It is similar to
the `increment` method, but it also receives funds from the user and stores them
in the contract.

```typescript theme={null}
// Execute a message to donate to the contract.
const executeMsg = { donate: {} };

// Funds are attached via overrides. This example is specific to ethers.js
const overrides = {
  value: ethers.parseEther('3.2') // Sending 3.2 sei
};
const executeResponse = await contract.execute(
  COUNTER_CONTRACT_ADDRESS,
  toUtf8Bytes(JSON.stringify(executeMsg)),
  toUtf8Bytes(JSON.stringify([])), // No Bank Module funds attached
  overrides
);

await executeResponse.wait();
const receipt = await provider.getTransactionReceipt(executeResponse.hash);
```

For payable contracts, attach native SEI through `msg.value`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.