Skip to content

Instantly share code, notes, and snippets.

@cordt-sei
Created December 22, 2024 17:51
Show Gist options
  • Save cordt-sei/73f0a1f2aecc5fc8e5777a98a026a4bb to your computer and use it in GitHub Desktop.
Save cordt-sei/73f0a1f2aecc5fc8e5777a98a026a4bb to your computer and use it in GitHub Desktop.
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { JsonRpcProvider, Wallet, Contract } from 'ethers';
import dotenv from 'dotenv';
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* The address of the IBC precompile contract.
* @category Cosmos Interoperability
*/
export const IBC_PRECOMPILE_ADDRESS = '0x0000000000000000000000000000000000001009';
/**
* The ABI for the IBC precompile contract.
* @category Cosmos Interoperability
*/
export const IBC_PRECOMPILE_ABI = [
{
inputs: [
{ internalType: 'string', name: 'toAddress', type: 'string' },
{ internalType: 'string', name: 'port', type: 'string' },
{ internalType: 'string', name: 'channel', type: 'string' },
{ internalType: 'string', name: 'denom', type: 'string' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
{ internalType: 'uint64', name: 'revisionNumber', type: 'uint64' },
{ internalType: 'uint64', name: 'revisionHeight', type: 'uint64' },
{ internalType: 'uint64', name: 'timeoutTimestamp', type: 'uint64' },
{ internalType: 'string', name: 'memo', type: 'string' }
],
name: 'transfer',
outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }],
stateMutability: 'payable',
type: 'function'
},
{
inputs: [
{ internalType: 'string', name: 'toAddress', type: 'string' },
{ internalType: 'string', name: 'port', type: 'string' },
{ internalType: 'string', name: 'channel', type: 'string' },
{ internalType: 'string', name: 'denom', type: 'string' },
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
{ internalType: 'string', name: 'memo', type: 'string' }
],
name: 'transferWithDefaultTimeout',
outputs: [{ internalType: 'bool', name: 'success', type: 'bool' }],
stateMutability: 'payable',
type: 'function'
}
];
async function main() {
const SEI_RPC_URL = process.env.SEI_RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const seiProvider = new JsonRpcProvider(SEI_RPC_URL);
const wallet = new Wallet(PRIVATE_KEY, seiProvider);
const ibcContract = new Contract(IBC_PRECOMPILE_ADDRESS, IBC_PRECOMPILE_ABI, wallet);
console.log("IBC Contract Instance:", ibcContract);
console.log("Available ABI Methods:", ibcContract.interface.fragments);
const currentBlockNumber = await seiProvider.getBlockNumber();
console.log("Current Block Number:", currentBlockNumber);
const zenrockBlockTime = 2; // Zenrock block time in seconds
const timeoutDuration = 600; // Timeout duration in seconds (10 minutes)
const zenrockBlocks = Math.ceil(timeoutDuration / zenrockBlockTime);
const revisionHeight = currentBlockNumber + zenrockBlocks;
const revisionNumber = 1; // Assume Sei's revision number is 1
const timeoutTimestamp = Math.floor(Date.now() / 1000) + timeoutDuration;
const toAddress = "zen1wev8ptzj27aueu04wgvvl4gvurax6rj5nz7l0l";
const port = "transfer";
const channel = "channel-78";
const denom = "usei"; // Ensure this matches the expected native token denom
const amount = BigInt(1); // Sending 1usei
const memo = "";
console.log("Transfer Parameters:");
console.log({
toAddress,
port,
channel,
denom,
amount: amount.toString(),
revisionNumber,
revisionHeight,
timeoutTimestamp,
memo,
});
try {
console.log("Performing a dry-run...");
const result = await ibcContract.callStatic.transfer(
toAddress,
port,
channel,
denom,
amount,
revisionNumber,
revisionHeight,
timeoutTimestamp,
memo
);
console.log("Dry-run result:", result);
} catch (error) {
console.error("Error during dry-run:", error.reason || error.message);
return;
}
try {
console.log("Sending IBC Transfer...");
const tx = await ibcContract.transfer(
toAddress,
port,
channel,
denom,
amount,
revisionNumber,
revisionHeight,
timeoutTimestamp,
memo,
{
gasLimit: BigInt(1_000_000),
}
);
console.log("Transaction sent, hash:", tx.hash);
const receipt = await tx.wait();
console.log("Transaction confirmed in block:", receipt.blockNumber);
} catch (error) {
console.error("Error occurred during IBC transfer:", error.reason || error.message);
}
}
main().catch((error) => {
console.error("Error in script:", error.message);
process.exit(1);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment