Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
248883c
feat: TS version of mainProcessor and config handler
kulikthebird Sep 17, 2025
1c02f02
refactor: use TS mainProcessor in JS scripts
kulikthebird Sep 17, 2025
65b9f81
Merge branch 'main' into feat/main_processor_ts
kulikthebird Sep 17, 2025
76a76e2
Merge branch 'main' into feat/main_processor_ts
nbayindirli Sep 19, 2025
3625663
Merge branch 'feat/main_processor_ts' into chore/use_ts_main_processor
nbayindirli Sep 19, 2025
adebc3f
Merge branch 'main' into feat/main_processor_ts
blockchainguyy Sep 22, 2025
263bdc4
refactor: ConfigManager - enhanced config scheme ; prints reach outpu…
kulikthebird Sep 22, 2025
f0081f2
refactoring: removed TODO - covered by a task ; generic type extraction
kulikthebird Sep 22, 2025
9ab2ccd
chore: required fields fix ; loop instead of single checks
kulikthebird Sep 22, 2025
da4dff5
chore: remove generic arg
kulikthebird Sep 23, 2025
2823b7a
fix: required fields check - zeros are correct values
kulikthebird Sep 23, 2025
4dc6bdd
Merge branch 'feat/main_processor_ts' into chore/use_ts_main_processor
kulikthebird Sep 23, 2025
94bd68f
Apply suggestion from @nbayindirli
kulikthebird Sep 23, 2025
cadcec2
fix: remove undefined export
kulikthebird Sep 23, 2025
c6786bb
Merge branch 'main' into feat/main_processor_ts
kulikthebird Sep 23, 2025
06765b5
fix: gasLimit & gasPrice validation
kulikthebird Sep 23, 2025
99937be
fix: import
kulikthebird Sep 23, 2025
9a1f31e
fix: imports
kulikthebird Sep 23, 2025
08e2446
fix: remove saveConfig from query - it's saved in mainProcessor
kulikthebird Sep 23, 2025
b7de9bb
Merge branch 'feat/main_processor_ts' into chore/use_ts_main_processor
kulikthebird Sep 23, 2025
693d560
Apply suggestion from @nbayindirli
kulikthebird Sep 23, 2025
c7fb43b
Apply suggestion from @nbayindirli
kulikthebird Sep 23, 2025
17113ca
Merge branch 'feat/main_processor_ts' into chore/use_ts_main_processor
kulikthebird Sep 23, 2025
942e783
Merge branch 'main' into feat/main_processor_ts
kulikthebird Sep 24, 2025
5849332
Merge branch 'feat/main_processor_ts' into chore/use_ts_main_processor
kulikthebird Sep 24, 2025
5ad8882
Merge branch 'main' into chore/use_ts_main_processor
kulikthebird Sep 24, 2025
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
128 changes: 128 additions & 0 deletions common/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { StdFee } from '@cosmjs/stargate';
import { GasPrice, calculateFee } from '@cosmjs/stargate';

import { loadConfig, saveConfig } from '.';

export interface FullConfig {
axelar: {
contracts: {
[key: string]: ContractConfig & {
governanceAddress?: string;
governanceAccount?: string;
};
};
rpc: string;
gasPrice: string;
gasLimit: string | number;
govProposalInstantiateAddresses: string[];
govProposalDepositAmount: string;
};
chains: {
[chainName: string]: ChainConfig;
};
[key: string]: unknown;
}

export interface ChainConfig {
name: string;
axelarId: string;
chainId: number;
rpc: string;
tokenSymbol: string;
decimals: number;
confirmations?: number;
chainType: string;
contracts: {
[key: string]: ContractConfig;
};
}

export interface ContractConfig {
address?: string;
codeId?: number;
storeCodeProposalCodeHash?: string;
storeCodeProposalId?: string;
lastUploadedCodeId?: number;
[key: string]: unknown;
}

export class ConfigManager {
private environment: string;
private fullConfig: FullConfig;

constructor(environment: string, fullConfig?: FullConfig) {
this.environment = environment;

if (fullConfig) {
this.fullConfig = fullConfig;
} else {
this.fullConfig = loadConfig(this.environment);
}

this.validateConfig();
}

private validateConfig(): void {
if (!this.fullConfig.axelar) {
throw new Error(`Missing 'axelar' section in ${this.environment} config`);
}

if (!this.fullConfig.axelar.contracts) {
throw new Error(`Missing 'axelar.contracts' section in ${this.environment} config`);
}

if (!this.fullConfig.chains) {
throw new Error(
`Missing 'chains' section in ${this.environment} config. Please ensure the config file has a 'chains' property.`,
);
}

if (typeof this.fullConfig.chains !== 'object' || this.fullConfig.chains === null) {
throw new Error(`'chains' section in ${this.environment} config must be an object`);
}

if (!this.fullConfig.axelar.rpc) {
throw new Error(`Missing 'axelar.rpc' in ${this.environment} config`);
}

if (!this.fullConfig.axelar.gasPrice) {
throw new Error(`Missing 'axelar.gasPrice' in ${this.environment} config`);
}

if (!this.fullConfig.axelar.gasLimit) {
throw new Error(`Missing 'axelar.gasLimit' in ${this.environment} config`);
}
}

public initContractConfig(contractName: string, chainName: string) {
if (!this.fullConfig.axelar.contracts[contractName]) {
this.fullConfig.axelar.contracts[contractName] = {};
}

if (chainName) {
this.fullConfig.axelar.contracts[contractName][chainName] = this.fullConfig.axelar.contracts[contractName][chainName] || {};
}
}

public saveConfig(): void {
saveConfig(this.fullConfig, this.environment);
}

public getFullConfig(): FullConfig {
return this.fullConfig;
}

public getProposalInstantiateAddresses(): string[] {
return this.fullConfig.axelar.govProposalInstantiateAddresses;
}

public getProposalDepositAmount(): string {
return this.fullConfig.axelar.govProposalDepositAmount;
}

public getFee(): string | StdFee {
const { gasPrice, gasLimit } = this.fullConfig.axelar;

return gasLimit === 'auto' ? 'auto' : calculateFee(gasLimit as number, GasPrice.fromString(gasPrice));
}
}
11 changes: 0 additions & 11 deletions common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -756,16 +756,6 @@ function encodeITSDestination(chains, destinationChain, destinationAddress) {
}
}

const getProposalConfig = (config, env, key) => {
try {
const value = config.axelar?.[key];
if (value === undefined) throw new Error(`Key "${key}" not found in config for ${env}`);
return value;
} catch (error) {
throw new Error(`Failed to load config value "${key}" for ${env}: ${error.message}`);
}
};

/**
* Validates if a chain is valid in the config.
*
Expand Down Expand Up @@ -856,7 +846,6 @@ module.exports = {
getCurrentVerifierSet,
asciiToBytes,
encodeITSDestination,
getProposalConfig,
tokenManagerTypes,
validateLinkType,
validateChain,
Expand Down
21 changes: 3 additions & 18 deletions cosmwasm/deploy-contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ require('../common/cli-utils');

const { instantiate2Address } = require('@cosmjs/cosmwasm-stargate');

const { printInfo, loadConfig, saveConfig, prompt } = require('../common');
const { printInfo, prompt } = require('../common');

const {
CONTRACTS,
prepareWallet,
prepareClient,
fromHex,
getSalt,
initContractConfig,
getAmplifierContractConfig,
getCodeId,
uploadContract,
instantiateContract,
migrateContract,
} = require('./utils');

const { mainProcessor } = require('./processor');

const { Command } = require('commander');
const { addAmplifierOptions } = require('./cli-utils');

Expand Down Expand Up @@ -87,20 +86,6 @@ const migrate = async (client, wallet, config, options) => {
printInfo('Migration completed. Transaction hash', transactionHash);
};

const mainProcessor = async (processor, options) => {
const { env } = options;
const config = loadConfig(env);

initContractConfig(config, options);

const wallet = await prepareWallet(options);
const client = await prepareClient(config, wallet);

await processor(client, wallet, config, options);

saveConfig(config, env);
};

const programHandler = () => {
const program = new Command();

Expand Down
48 changes: 48 additions & 0 deletions cosmwasm/processor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';
import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing';
import { StdFee } from '@cosmjs/stargate';

import { ConfigManager, FullConfig } from '../common/config';
import { prepareClient, prepareWallet } from './utils';

type Options = {
env: string;
contractName: string;
chainName: string;
mnemonic: string;
runAs?: string;
deposit?: string;
instantiateAddresses?: string[];
};

export async function mainProcessor<
Processor extends (
client: SigningCosmWasmClient,
wallet: DirectSecp256k1HdWallet,
config: FullConfig,
options: Options,
args?: string[],
fee?: string | StdFee,
) => Promise<void>,
>(processor: Processor, options: Options, args?: string[]) {
const { runAs, deposit, instantiateAddresses, env } = options;
const configManager = new ConfigManager(env);

// TODO tkulik: The `runAs` should be moved to config
options.runAs =
runAs ||
(env == 'devnet-amplifier' ? 'axelar1zlr7e5qf3sz7yf890rkh9tcnu87234k6k7ytd9' : 'axelar10d07y265gmmuvt4z0w9aw880jnsr700j7v9daj');
options.deposit = deposit || configManager.getProposalDepositAmount();
options.instantiateAddresses = instantiateAddresses || configManager.getProposalInstantiateAddresses();

configManager.initContractConfig(options.contractName, options.chainName);

const wallet = await prepareWallet(options);
const client = await prepareClient(configManager.getFullConfig(), wallet);

const fee = configManager.getFee();

await processor(client, wallet, configManager.getFullConfig(), options, args, fee);

configManager.saveConfig();
}
39 changes: 13 additions & 26 deletions cosmwasm/query.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
'use strict';

const { prepareDummyWallet, prepareClient, initContractConfig } = require('./utils');
const { loadConfig, printInfo, printWarn, getChainConfig, itsHubContractAddress, saveConfig } = require('../common');
const { printInfo, printWarn, getChainConfig, itsHubContractAddress, saveConfig } = require('../common');
const { Command } = require('commander');
const { addAmplifierQueryOptions } = require('./cli-utils');

async function rewards(client, config, args, options) {
async function rewards(client, _wallet, config, _options, args, _fee) {
const [chainName] = args;

const rewardsContractAddresses = {
Expand Down Expand Up @@ -45,7 +44,7 @@ async function getItsChainConfig(client, config, chainName) {
});
}

async function tokenConfig(client, config, args, _options) {
async function tokenConfig(client, _wallet, config, _options, args, _fee) {
const [tokenId] = args;
const itsHubAddress = itsHubContractAddress(config.axelar);

Expand All @@ -65,7 +64,7 @@ async function tokenConfig(client, config, args, _options) {
}
}

async function customTokenMetadata(client, config, args, options) {
async function customTokenMetadata(client, _wallet, config, _options, args, _fee) {
const [chainName, tokenAddress] = args;
const itsHubAddress = itsHubContractAddress(config.axelar);

Expand Down Expand Up @@ -94,7 +93,7 @@ async function customTokenMetadata(client, config, args, options) {
}
}

async function tokenInstance(client, config, args, options) {
async function tokenInstance(client, _wallet, config, _options, args, _fee) {
const [chainName, tokenId] = args;
const itsHubAddress = itsHubContractAddress(config.axelar);

Expand Down Expand Up @@ -123,7 +122,7 @@ async function tokenInstance(client, config, args, options) {
}
}

async function itsChainConfig(client, config, args, options) {
async function itsChainConfig(client, _wallet, config, _options, args, _fee) {
const [chainName] = args;

try {
Expand All @@ -134,7 +133,7 @@ async function itsChainConfig(client, config, args, options) {
}
}

async function saveDeployedContracts(client, config, args, options) {
async function saveDeployedContracts(client, _wallet, config, _options, args, _fee) {
const [chainName] = args;

const coordinatorAddress = config.axelar?.contracts?.Coordinator?.address;
Expand Down Expand Up @@ -204,18 +203,6 @@ async function saveDeployedContracts(client, config, args, options) {
printInfo(`Config updated successfully for ${chainName}`);
}

const mainProcessor = async (processor, args, options) => {
const { env } = options;
const config = loadConfig(env);

initContractConfig(config, options);

const wallet = await prepareDummyWallet(options);
const client = await prepareClient(config, wallet);

await processor(client, config, args, options);
};

const programHandler = () => {
const program = new Command();

Expand All @@ -225,42 +212,42 @@ const programHandler = () => {
.command('rewards <chainName>')
.description('Query rewards pool state for multisig and voting_verifier contracts')
.action((chainName, options) => {
mainProcessor(rewards, [chainName], options);
mainProcessor(rewards, options, [chainName]);
});

const tokenConfigCmd = program
.command('token-config <tokenId>')
.description('Query token config from ITS Hub')
.action((tokenId, options) => {
mainProcessor(tokenConfig, [tokenId], options);
mainProcessor(tokenConfig, options, [tokenId]);
});

const customTokenMetadataCmd = program
.command('custom-token-metadata <chainName> <tokenAddress>')
.description('Query custom token metadata by chain name and token address')
.action((chainName, tokenAddress, options) => {
mainProcessor(customTokenMetadata, [chainName, tokenAddress], options);
mainProcessor(customTokenMetadata, options, [chainName, tokenAddress]);
});

const tokenInstanceCmd = program
.command('token-instance <chainName> <tokenId>')
.description('Query token instance by chain name and token ID')
.action((chainName, tokenId, options) => {
mainProcessor(tokenInstance, [chainName, tokenId], options);
mainProcessor(tokenInstance, options, [chainName, tokenId]);
});

const itsChainConfigCmd = program
.command('its-chain-config <chainName>')
.description('Query ITS chain configuration for a specific chain')
.action((chainName, options) => {
mainProcessor(itsChainConfig, [chainName], options);
mainProcessor(itsChainConfig, options, [chainName]);
});

const saveDeployedContractsCmd = program
.command('save-deployed-contracts <chainName>')
.description('Query and save deployed Gateway, VotingVerifier and MultisigProver contracts via Coordinator')
.action((chainName, options) => {
mainProcessor(saveDeployedContracts, [chainName], options);
mainProcessor(saveDeployedContracts, options, [chainName]);
});

addAmplifierQueryOptions(rewardsCmd);
Expand Down
Loading