import { createWalletClient, createPublicClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import {
seiTestnet,
WASM_PRECOMPILE_ABI,
WASM_PRECOMPILE_ADDRESS
} from '@sei-js/precompiles/viem';
const account = privateKeyToAccount('0x...');
const walletClient = createWalletClient({
account,
chain: seiTestnet,
transport: http()
});
const publicClient = createPublicClient({
chain: seiTestnet,
transport: http()
});
// Query contract
async function queryContract(contractAddress: string, queryMsg: any) {
const encodedQuery = new TextEncoder().encode(JSON.stringify(queryMsg));
const response = await publicClient.readContract({
address: WASM_PRECOMPILE_ADDRESS,
abi: WASM_PRECOMPILE_ABI,
functionName: 'query',
args: [contractAddress, `0x${Buffer.from(encodedQuery).toString('hex')}`]
});
// Decode response
const decoded = new TextDecoder().decode(
new Uint8Array(Buffer.from(response.slice(2), 'hex'))
);
return JSON.parse(decoded);
}
// Execute contract
async function executeContract(
contractAddress: string,
executeMsg: any,
funds: Array<{ denom: string; amount: string }> = []
) {
const encodedMsg = new TextEncoder().encode(JSON.stringify(executeMsg));
const encodedCoins = new TextEncoder().encode(JSON.stringify(funds));
const { request } = await publicClient.simulateContract({
address: WASM_PRECOMPILE_ADDRESS,
abi: WASM_PRECOMPILE_ABI,
functionName: 'execute',
args: [
contractAddress,
`0x${Buffer.from(encodedMsg).toString('hex')}`,
`0x${Buffer.from(encodedCoins).toString('hex')}`
],
value: parseEther('0.01'),
account
});
const hash = await walletClient.writeContract(request);
return await publicClient.waitForTransactionReceipt({ hash });
}
// Instantiate contract
async function instantiateContract(
codeId: number,
initMsg: any,
label: string,
admin?: string,
funds: Array<{ denom: string; amount: string }> = []
) {
const encodedMsg = new TextEncoder().encode(JSON.stringify(initMsg));
const encodedCoins = new TextEncoder().encode(JSON.stringify(funds));
const { request } = await publicClient.simulateContract({
address: WASM_PRECOMPILE_ADDRESS,
abi: WASM_PRECOMPILE_ABI,
functionName: 'instantiate',
args: [
BigInt(codeId),
admin || account.address,
`0x${Buffer.from(encodedMsg).toString('hex')}`,
label,
`0x${Buffer.from(encodedCoins).toString('hex')}`
],
value: parseEther('0.05'),
account
});
const hash = await walletClient.writeContract(request);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
// Extract contract address from logs
return {
transactionHash: hash,
contractAddress: receipt.logs[0]?.data, // Parse from logs
gasUsed: receipt.gasUsed
};
}
// Batch execute
async function batchExecute(executions: Array<{
contractAddress: string;
msg: any;
funds?: Array<{ denom: string; amount: string }>;
}>) {
const executeMsgs = executions.map(exec => ({
contractAddress: exec.contractAddress,
msg: `0x${Buffer.from(JSON.stringify(exec.msg)).toString('hex')}`,
coins: `0x${Buffer.from(JSON.stringify(exec.funds || [])).toString('hex')}`
}));
const { request } = await publicClient.simulateContract({
address: WASM_PRECOMPILE_ADDRESS,
abi: WASM_PRECOMPILE_ABI,
functionName: 'execute_batch',
args: [executeMsgs],
value: parseEther('0.02'),
account
});
const hash = await walletClient.writeContract(request);
return await publicClient.waitForTransactionReceipt({ hash });
}
// Contract manager class
class CosmWasmManager {
async deployAndSetup(
codeId: number,
initMsg: any,
setupMsgs: any[],
label: string
) {
// 1. Instantiate contract
const deployment = await instantiateContract(codeId, initMsg, label);
// 2. Execute setup messages
const setupExecutions = setupMsgs.map(msg => ({
contractAddress: deployment.contractAddress,
msg
}));
const setupResult = await batchExecute(setupExecutions);
return {
contractAddress: deployment.contractAddress,
deploymentTx: deployment.transactionHash,
setupTx: setupResult.transactionHash
};
}
async queryMultiple(queries: Array<{
contractAddress: string;
msg: any;
}>) {
const results = await Promise.all(
queries.map(query => queryContract(query.contractAddress, query.msg))
);
return queries.map((query, index) => ({
contractAddress: query.contractAddress,
query: query.msg,
result: results[index]
}));
}
}
// Example usage
const manager = new CosmWasmManager();
// Query contract state
const balance = await queryContract("sei1...", { balance: { address: "sei1..." } });
console.log('Balance:', balance);
// Execute transfer
const transferResult = await executeContract("sei1...", {
transfer: {
recipient: "sei1...",
amount: "1000000"
}
});
console.log('Transfer completed:', transferResult.transactionHash);