Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4f7c659
test(evm): use -b sync + sleep in lib.js cosmos-tx helpers for Autobahn
wen-coding May 1, 2026
88e6078
test(evm): also flip associateKey and passProposal vote to -b sync
wen-coding May 1, 2026
bb426e2
Merge branch 'main' into wen/fix_evm_hardhat_lib_for_autobahn
wen-coding May 1, 2026
52eb5a0
test(evm): revert executeWasm/associateWasm to -b block
wen-coding May 1, 2026
6b9be10
test(evm): replace fixed sleep(2000) with waitForBlocks(1) helper
wen-coding May 1, 2026
7bd996a
test(evm): bump waitForBlocks default to 2 to close empty-block race
wen-coding May 1, 2026
8ccabdd
Merge branch 'main' into wen/fix_evm_hardhat_lib_for_autobahn
wen-coding May 4, 2026
7c45e68
Merge branch 'main' into wen/fix_evm_hardhat_lib_for_autobahn
wen-coding May 4, 2026
d282033
test(evm): convert evmSend and proposeParamChange off -b block
wen-coding May 4, 2026
0fb35a3
test(evm): convert createTokenFactoryTokenAndMint off -b block
wen-coding May 4, 2026
0afffb9
test(evm): convert EVMPrecompileTest Gov before-hook off -b block
wen-coding May 5, 2026
446439b
Merge branch 'main' into wen/fix_evm_hardhat_lib_for_autobahn
wen-coding May 7, 2026
2a42c73
test(evm): drop migration-history framing from lib.js comments
wen-coding May 13, 2026
e82202d
Merge branch 'main' into wen/fix_evm_hardhat_lib_for_autobahn
wen-coding May 13, 2026
7cb7df3
test(evm): load gov proposal fields from param_change_proposal.json
wen-coding May 13, 2026
9cb1fb2
test(evm): verify polled proposal title matches submitted in proposeP…
wen-coding May 13, 2026
4738537
test(evm): minimize diff in createTokenFactoryTokenAndMint
wen-coding May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions contracts/test/EVMPrecompileTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const fs = require('fs');
const path = require('path');

const { expectRevert } = require('@openzeppelin/test-helpers');
const { setupSigners, getAdmin, deployWasm, storeWasm, execute, isDocker, ABI, createTokenFactoryTokenAndMint, getSeiBalance, rawHttpDebugTraceWithCallTracer} = require("./lib");
const { setupSigners, getAdmin, deployWasm, storeWasm, execute, isDocker, ABI, createTokenFactoryTokenAndMint, getSeiBalance, rawHttpDebugTraceWithCallTracer, proposeParamChange} = require("./lib");

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
Expand Down Expand Up @@ -125,8 +125,16 @@ describe("EVM Precompile Tester", function () {
let govProposal;

before(async function () {
const govProposalResponse = JSON.parse(await execute(`seid tx gov submit-proposal param-change ../contracts/test/param_change_proposal.json --from admin --fees 20000usei -b block -y -o json`))
govProposal = govProposalResponse.logs[0].events[3].attributes[1].value;
const proposalSpec = require('./param_change_proposal.json');
govProposal = await proposeParamChange(
proposalSpec.title,
proposalSpec.description,
proposalSpec.changes,
"200000000usei",
"20000usei",
"admin",
proposalSpec.is_expedited,
);

const signer = accounts[0].signer
const contractABIPath = '../../precompiles/gov/abi.json';
Expand Down
88 changes: 70 additions & 18 deletions contracts/test/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ async function delay() {
await sleep(1000)
}

// Default 2 because the very next block after submit can be empty
// (tx still in mempool, lands one block later).
async function waitForBlocks(blocks=2, timeoutMs=15000) {
const start = await ethers.provider.getBlockNumber()
const deadline = Date.now() + timeoutMs
while (Date.now() < deadline) {
const cur = await ethers.provider.getBlockNumber()
if (cur >= start + blocks) return
await sleep(50)
}
throw new Error(`block didn't advance by ${blocks} in ${timeoutMs}ms (start=${start})`)
}

async function getCosmosTx(provider, evmTxHash) {
return await provider.send("sei_getCosmosTx", [evmTxHash])
}
Expand All @@ -92,18 +105,21 @@ async function fundAddress(addr, amount="1000000000000000000000") {
}

async function evmSend(addr, fromKey, amount="10000000000000000000000000") {
const output = await execute(`seid tx evm send ${addr} ${amount} --from ${fromKey} -b block -y`);
const output = await execute(`seid tx evm send ${addr} ${amount} --from ${fromKey} -b sync -y`);
await waitForBlocks()
return output.replace(/.*0x/, "0x").trim()
}

async function bankSend(toAddr, fromKey, amount="100000000000", denom="usei") {
const result = await execute(`seid tx bank send ${fromKey} ${toAddr} ${amount}${denom} -b block --fees 20000usei -y`);
await delay()
const result = await execute(`seid tx bank send ${fromKey} ${toAddr} ${amount}${denom} -b sync --fees 20000usei -y`);
await waitForBlocks()
return result
}

async function fundSeiAddress(seiAddr, amount="100000000000", denom="usei", funder=adminKeyName) {
return await execute(`seid tx bank send ${funder} ${seiAddr} ${amount}${denom} -b block --fees 20000usei -y`);
const result = await execute(`seid tx bank send ${funder} ${seiAddr} ${amount}${denom} -b sync --fees 20000usei -y`);
await waitForBlocks()
return result
}

async function getSeiBalance(seiAddr, denom="usei") {
Expand Down Expand Up @@ -155,8 +171,8 @@ async function getKeySeiAddress(name) {

async function associateKey(keyName) {
try {
await execute(`seid tx evm associate-address --from ${keyName} -b block`)
await delay()
await execute(`seid tx evm associate-address --from ${keyName} -b sync`)
await waitForBlocks()
}catch(e){
console.log("skipping associate")
}
Expand Down Expand Up @@ -219,15 +235,18 @@ async function rawHttpDebugTraceWithCallTracer(txHash) {
}

async function createTokenFactoryTokenAndMint(name, amount, recipient, from=adminKeyName) {
const command = `seid tx tokenfactory create-denom ${name} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
const output = await execute(command);
const response = JSON.parse(output)
const token_denom = getEventAttribute(response, "create_denom", "new_token_denom")
const mint_command = `seid tx tokenfactory mint ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
const command = `seid tx tokenfactory create-denom ${name} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json`
await execute(command);
// Tokenfactory denom is deterministic: factory/<creator-bech32>/<subdenom>.
const token_denom = `factory/${await getKeySeiAddress(from)}/${name}`
await waitForBlocks()
const mint_command = `seid tx tokenfactory mint ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json`
await execute(mint_command);
await waitForBlocks()

const send_command = `seid tx bank send ${from} ${recipient} ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode block -o json`
const send_command = `seid tx bank send ${from} ${recipient} ${amount}${token_denom} --from ${from} --gas=5000000 --fees=1000000usei -y --broadcast-mode sync -o json`
await execute(send_command);
await waitForBlocks()
return token_denom
}

Expand Down Expand Up @@ -402,19 +421,52 @@ async function proposeParamChange(title, description, changes, deposit="20000000
};
const proposalJson = JSON.stringify(proposal);
const tempFile = `/tmp/param_change_${Date.now()}.json`;

// Use base64 encoding to avoid quote escaping issues in Docker
const base64Json = Buffer.from(proposalJson).toString('base64');
await execute(`echo ${base64Json} | base64 -d > ${tempFile}`);

const command = `seid tx gov submit-proposal param-change ${tempFile} --from ${from} --fees ${fees} -y -o json --broadcast-mode=block`;

// Identify the new proposal by diffing gov state before vs after submit.
const maxIdBefore = await maxProposalId();

const command = `seid tx gov submit-proposal param-change ${tempFile} --from ${from} --fees ${fees} -y -o json -b sync`;
const output = await execute(command);
await execute(`rm ${tempFile}`);
const response = JSON.parse(output);
if (response.code !== 0) {
throw new Error(`Failed to submit proposal: ${response.raw_log}`);
}
return getEventAttribute(response, "submit_proposal", "proposal_id");

const deadline = Date.now() + 30000;
while (Date.now() < deadline) {
const cur = await maxProposalId();
if (cur > maxIdBefore) {
const detail = JSON.parse(await execute(`seid q gov proposal ${cur} -o json`));
const observedTitle = detail.content?.title ?? detail.title;
if (observedTitle !== title) {
throw new Error(`proposal ${cur} title "${observedTitle}" does not match submitted "${title}" — concurrent submission?`);
}
return String(cur);
}
await sleep(250);
}
throw new Error(`proposal submitted (tx ${response.txhash}) but did not appear in gov state within 30s`);
}

// Returns the highest existing proposal id, or 0 if there are no proposals.
async function maxProposalId() {
let out;
try {
// seid exits non-zero ("Error: no proposals found") on an empty
// gov set; the try/catch treats that as id=0.
out = await execute(`seid q gov proposals --reverse --limit 1 -o json 2>/dev/null`);
} catch (e) {
return 0;
}
if (!out || !out.trim()) return 0;
const proposals = JSON.parse(out).proposals || [];
if (proposals.length === 0) return 0;
return Number(proposals[0].proposal_id || proposals[0].id);
}

async function proposeDisableWasm(title="Disable WASM", description="Disable cosmwasm store code and instantiate operations", deposit="200000000usei", fees="200000usei", from=adminKeyName) {
Expand Down Expand Up @@ -498,9 +550,9 @@ async function ensureWasmDisabled(from=adminKeyName) {

async function passProposal(proposalId, desposit="200000000usei", fees="200000usei", from=adminKeyName) {
if(await isDocker()) {
await executeOnAllNodes(`seid tx gov vote ${proposalId} yes --from node_admin -b block -y --fees ${fees}`)
await executeOnAllNodes(`seid tx gov vote ${proposalId} yes --from node_admin -b sync -y --fees ${fees}`)
} else {
await execute(`seid tx gov vote ${proposalId} yes --from ${from} -b block -y --fees ${fees}`)
await execute(`seid tx gov vote ${proposalId} yes --from ${from} -b sync -y --fees ${fees}`)
}
// Poll for proposal status with shorter delay for faster tests
for(let i=0; i<200; i++) {
Expand Down
Loading