Action required: IBC assets on Sei will become inaccessible If you hold USDC.n (USDC via Noble), USDT.kava (Kava USDT), Wormhole-bridged tokens, or any other IBC asset on Sei, you must swap, migrate, or bridge out before the governance proposal to disable inbound/outbound IBC transfers passes and is activated to avoid permanent loss of access. After this, Sei will no longer support IBC bridging of assets from Cosmos-based chains to and from Sei Network. Consult the SIP-03 Migration Guide for the full list of affected assets, required actions, and supported routes. For USDC.n specifically, see: Holders of USDC.n Need to Swap or Migrate.
Learn how to interact with Sei precompiles using ethers.js to query and execute CosmWasm contracts from the EVM.
Per Proposal 115, no new CosmWasm contracts can be deployed on Sei. The examples below apply to pre-existing CosmWasm contracts only — instantiate() will revert. Separately, Proposal 116 disables inbound IBC transfers as part of the SIP-03 migration.
The Sei precompiles can be used like any standard smart contract on the EVM. For
example, using ethers.js, you can query and
execute actions on an existing CosmWasm contract as follows:
To install ethers, run the following command in your project directory
terminal:
npm install ethersnpm install @sei-js/evm
Next, you’ll need to use one of the precompiles in EVM Precompiles section. In
this example, we’re going to be using the wasmd precompile:
// Import Wasm precompile address and ABI// View the entire ABI here: https://github.com/sei-protocol/sei-chain/tree/evm/precompiles/wasmdimport { WASM_PRECOMPILE_ABI, WASM_PRECOMPILE_ADDRESS } from '@sei-js/evm';
Next, we’ll set up a provider and contract to interact with the blockchain:
import { ethers, toUtf8Bytes, toUtf8String } from 'ethers';// Using MetaMask as the signer and providerconst provider = new ethers.BrowserProvider(window.ethereum);const signer = await provider.getSigner();// Create a contract with the signerconst contract = new ethers.Contract(WASM_PRECOMPILE_ADDRESS, WASM_PRECOMPILE_ABI, signer);
Once you have the contract, you can query and execute messages to any CosmWasm
smart contract. In the below example we assume there is a counter contract with a get_count function
// Replace with your contractconst 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 confirmedawait executeResponse.wait();console.log(executeResponse);
In this example, we execute the ‘donate’ method on our contract. This is similar
to the increment method, but also receives funds from the user and stores it
in the contract.
// Execute a message to donate to the contract.const executeMsg = { donate: {} };// Funds are attached via overrides. This example is specific to ethers.jsconst 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([{ denom: 'uusdc', amount: '100' }])), // Also send 100 uusdc overrides);await executeResponse.wait();const receipt = await provider.getTransactionReceipt(executeResponse.hash);
For payable contracts, Sei amounts have to be sent directly to the contract
while other denoms should use the coins field.