Created
December 22, 2024 17:51
-
-
Save cordt-sei/73f0a1f2aecc5fc8e5777a98a026a4bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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